<template>
  <div class="map-container" id="map-container" :style="Object.assign(mapComponentSizeScale, mapComponentPaddingConfigStyle, mapPopupConfig.currentConfigStyle)">
    <div v-if="dataLoading" class="loading-mask" :style="mapMaskConfigStyle">
      <div class="loading-mask-spinner">
        <svg viewBox="25 25 50 50" class="circular">
          <circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
        </svg>
      </div>
    </div>
    <!-- 具名插槽部分 start -->
    <slot name="top"></slot>
    <div
      class="map-widget-domain-on-top-right"
      :style="Object.assign(mapWidgetDomainOnTopRightCssConfig.cssValue, { marginRight: (mapWidgetDomainOnTopRightCssConfig.value.width ? mapWidgetDomainOnTopRightCssConfig.value.width + mapWidgetDomainOnTopRightCssConfig.value.spacing : mapWidgetDomainOnTopRightCssConfig.value.width) + 'px' })"
    >
      <slot name="topRightWithMapWidgetDomain"></slot>
    </div>
    <slot name="topRight"></slot>
    <slot name="right"></slot>
    <slot name="bottomRight"></slot>
    <slot name="bottom"></slot>
    <slot name="bottomLeft"></slot>
    <slot name="left"></slot>
    <slot name="topLeft"></slot>
    <!-- 具名插槽部分 end -->
    <!-- 右上区域微件集合 start -->
    <div class="map-widget-domain-on-top-right" :style="mapWidgetDomainOnTopRightCssConfig.style">
      <!-- 边界切换工具微件 start -->
      <div v-if="isShowBoundsSwitchWidget && currentActiveBoundsSwitchButtons.length" class="widget-common bounds-switch-widget" @mouseenter="boundsSwitchWidgetOpenStatus = true" @mouseleave="boundsSwitchWidgetOpenStatus = false">
        <div class="widget-icon-container" :class="boundsShowStatus ? '' : 'widget-icon-container-close'" @click="boundsSwitch">
          <div class="widget-icon" :class="currentShowBoundsLevel !== null && currentShowBoundsLevel !== -1 && currentSelectedBoundsSwitchButton !== -1 ? `button-icon-${currentSelectedBoundsSwitchButton}${boundsSwitchWidgetOpenStatus ? '-selected' : ''}` : ''"></div>
        </div>
        <div v-if="boundsShowStatus" class="buttons-container">
          <div v-for="item,index in currentActiveBoundsSwitchButtons" class="button-container" :key="index" :style="{ cursor: currentShowBoundsLevel === item.realValue ? 'no-drop' : 'pointer' }" @click="boundsLoadController(item.realValue)">
            <div class="icon" :class="[`button-icon-${item.value}`, currentShowBoundsLevel === item.realValue ? `button-icon-${item.value}-selected` : '']"></div>
          </div>
        </div>
      </div>
      <!-- 边界切换工具微件 end -->
      <!-- 底图切换工具微件 start -->
      <div v-if="isShowBasemapSelectWidget && basemapsIndex.length" class="widget-common basemap-toggle-widget" @mouseenter="mapWidgetIncreaseWeight(true)" @mouseleave="mapWidgetIncreaseWeight(false)">
        <div class="widget-icon" :class="currentBasemapType ? `button-icon-${defaultBasemapsIndex.includes(currentBasemapType) ? currentBasemapType : Math.trunc(currentBasemapType / 10)}` : ''"></div>
        <div class="buttons-container">
          <div v-for="item,index in basemapsIndex" class="button-container" :key="index" :style="{ cursor: currentBasemapType === item ? 'no-drop' : 'pointer' }" @click="mapChangeController(item)">
            <div class="icon" :class="[`button-icon-${defaultBasemapsIndex.includes(item) ? item : Math.trunc(item / 10)}`, currentBasemapType === item ? `button-icon-${defaultBasemapsIndex.includes(item) ? item : Math.trunc(item / 10)}-selected` : '']"></div>
            <div class="tooltip-container">
              <div class="tooltip-content">
                <div class="scroll-wrap">
                  <div class="scroll-item">{{ basemapsName[item] }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 底图切换工具微件 end -->
      <!-- 测量&圈画框选工具微件 start -->
      <div v-if="isShowToolsBar && currentActiveToolBarButtons.length" class="widget-common measure-and-drawing-selection-widget">
        <div class="widget-icon"></div>
        <div class="buttons-container">
          <div v-for="item,index in currentActiveToolBarButtons" class="button-container" :key="index" @click="toolCommandLauncher(item.value)">
            <div class="button-common" :class="`button-${item.value}`">
              <div class="icon"></div>
              <div class="tooltip-container">
                <div class="tooltip-content">
                  <div class="scroll-wrap">
                    <div class="scroll-item">{{ item.name }}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 测量&圈画框选工具微件 end -->
      <!-- 恢复地图初始姿态微件 start -->
      <div v-if="isShowRestoreInitialStatusWidget" class="widget-common restore-initial-status-widget" @click="switchMapStatus(0)">
        <div class="widget-icon"></div>
      </div>
      <!-- 恢复地图初始姿态微件 end -->
    </div>
    <!-- 右上区域微件集合 end -->
    <!-- 状态栏微件 start -->
    <div v-if="isShowLocationBar && Object.keys(locationbarValues).length" class="location-bar-widget">
      <p>
        <span>层级：{{ locationbarValues.level }}</span>
        <span>经度：{{ locationbarValues.longitude ? locationbarValues.longitude : '--' }}</span>
        <span>纬度：{{ locationbarValues.latitude ?  locationbarValues.latitude : '--' }}</span>
      </p>
    </div>
    <!-- 状态栏微件 end -->
    <div v-if="mapMaskConfig.top" class="map-mask map-mask-top" :style="mapMaskConfigStyle"></div>
    <div v-if="mapMaskConfig.right" class="map-mask map-mask-right" :style="mapMaskConfigStyle"></div>
    <div v-if="mapMaskConfig.bottom" class="map-mask map-mask-bottom" :style="mapMaskConfigStyle"></div>
    <div v-if="mapMaskConfig.left" class="map-mask map-mask-left" :style="mapMaskConfigStyle"></div>
  </div>
</template>

<script>
import Vue from 'vue'
import 'mars3d/dist/mars3d.css'
import * as mars3d from 'mars3d'
import defaultIcon from '@assets/map/map-icon/map-icon-default.png'
import { deepMergeObject, componentSizeScale, getCurrentNetworkSituation } from '@utils'

Vue.prototype.$Imap = mars3d // 地图实例对象绑定到vue原型链上，可全局使用
Vue.prototype.$Cesium = mars3d.Cesium // cesium实例对象绑定到vue原型链上，可全局使用

export default {
  name: 'MapBase',
  props: {
    // 地图遮罩(mask)启用状态
    mapMask: {
      type: Object,
      required: false,
      default() {
        return {
          top: _const.mapConfigInfo.effectConfig.maskConfig.top.show,
          right: _const.mapConfigInfo.effectConfig.maskConfig.right.show,
          bottom: _const.mapConfigInfo.effectConfig.maskConfig.bottom.show,
          left: _const.mapConfigInfo.effectConfig.maskConfig.left.show
        }
      }
    },
    // 默认地图模式
    mapMode: {
      type: Number,
      required: false,
      default: 0 // 默认值为0(地图模式为2D平面模式)
    },
    // 默认地图姿态
    mapView: {
      type: Object,
      required: false,
      default() {
        return {
          lat: _const.mapConfigInfo.basicConfig[this.mapMode ? 'latTo3D' : 'latTo2D'], // 默认纬度值
          lng: _const.mapConfigInfo.basicConfig[this.mapMode ? 'lngTo3D' : 'lngTo2D'], // 默认经度值
          alt: _const.mapConfigInfo.basicConfig.alt, // 默认高度值
          heading: _const.mapConfigInfo.basicConfig.heading, // 默认旋转角度值
          pitch: _const.mapConfigInfo.basicConfig.pitch, // 默认倾斜角度值
          roll: _const.mapConfigInfo.basicConfig.roll // 默认翻滚角度值
        }
      }
    },
    // 默认地图相机视高范围
    mapCameraZoom: {
      type: Object,
      required: false,
      default() {
        return {
          minZoom: 466, // 默认最小视高
          maxZoom: 100000000 // 默认最大视高
        }
      }
    },
    // 默认加载地图底图类型
    showMapType: {
      type: Number,
      required: false,
      default: 2 // 默认值为2，可选值:2,3,4(,5)
    },
    // 状态栏微件展示控制
    isShowLocationBar: {
      type: Boolean,
      required: false,
      default: true // 默认值为true
    },
    // 恢复地图初始姿态微件展示控制
    isShowRestoreInitialStatusWidget: {
      type: Boolean,
      required: false,
      default: true // 默认值为true
    },
    // 测量&圈画框选工具条微件展示控制
    isShowToolsBar: {
      type: Boolean,
      required: false,
      default: true // 默认值为true
    },
    // 自定义配置展示测量&圈画框选工具条微件按钮
    toolsBarButtonsCustomConfig: {
      type: Array,
      required: false,
      default: () => [1, 1, 0, 0, 0] // 当前默认圈选按钮均为隐藏，其余为展示状态，1为展示，0为隐藏(只控制2个测量按钮、3个框选按钮共5个按钮的显隐控制，清除按钮跟随上述5个按钮显隐总状态，动态显隐[即5个按钮中存在某个按钮显示时，则此按钮显示；5个按钮均隐藏时，则此按钮隐藏])
    },
    // 边界切换微件展示控制
    isShowBoundsSwitchWidget: {
      type: Boolean,
      required: false,
      default: true // 默认值为true
    },
    // 底图切换微件展示控制
    isShowBasemapSelectWidget: {
      type: Boolean,
      required: false,
      default: true // 默认值为true
    },
    // 自定义配置展示边界切换微件层级按钮
    boundsSwitchWidgetButtonsCustomConfig: {
      type: Array,
      required: false,
      default: () => [1, 1, 1, 1, 1, 1] // 目前层级按钮为市域、片区、区县(市)、镇(乡)街、村社区、网格6级切换按钮，默认按钮均为展示状态，可用值为：1-展示，0-隐藏
    },
    // 展示边界系列控制
    boundsSeries: {
      type: Number,
      required: false,
      default: 0 // 默认值为0，可选值:根据全局配置项mapConfigInfo.boundsServiceConfig.boundsLayerInfo数组参数情况确定
    },
    // 默认展示边界层级
    defaultShowBoundsLevel: {
      type: Number,
      required: false,
      default: null // 默认值为null，可选值:-1-不显示边界、其他正整数值-根据全局配置项mapConfigInfo.boundsServiceConfig.boundsLayerInfo数组参数情况确定
    },
    // 边界显示相关参数配置(边界数据源为json时生效)
    /* 一、支持对全部边界显示统一配置，以及按边界显示层级独立配置(根据层级配置层级对象)，具体参数配置与boundsDisplayRelevantDefaultConfig参数相同，并可包含全局配置项mapConfigInfo.boundsServiceConfig.boundsLayerInfo中styleFieldOption对象参数配置，形如：
    二、使用优先级顺序为：按边界显示层级独立配置 > 全部边界显示统一配置 > 默认配置
    {
      isInteractive: true, ..., // 1.全部边界显示统一配置-基本属性配置
      note: {}, // 2.全部边界显示统一配置-注记属性配置
      styleFieldOption: {}, // 3.全部边界显示统一配置-styleFieldOption配置
      // 按边界显示层级独立配置对象(对象内部构造与全部边界显示统一配置(属性配置1、2、3)相同)
      0: {
        isInteractive: true, ...,
        note: {},
        styleFieldOption: {}
      },
      ...
    } */
    boundsDisplayRelevantConfig: {
      type: Object,
      require: false,
      default() {
        return {}
      } // 默认值为{}
    },
    // 地图姿态切换默认指定的地图层级
    defaultLevelWithSwitchMapStatus: {
      type: Number,
      required: false,
      default: 14 // 默认值为14，与地图混合聚合模式相关，与前端聚合起始层级保持一致
    }
  },
  data() {
    return {
      mapOriginalDesignSize: {
        width: 7680,
        height: 2160
      }, // 地图部件设计尺寸基准数值(同大屏原始设计尺寸保持一致)
      mapMaskConfig: {
        top: typeof (this.mapMask.top) !== 'undefined' ? this.mapMask.top : _const.mapConfigInfo.effectConfig.maskConfig.top.show,
        right: typeof (this.mapMask.right) !== 'undefined' ? this.mapMask.right : _const.mapConfigInfo.effectConfig.maskConfig.right.show,
        bottom: typeof (this.mapMask.bottom) !== 'undefined' ? this.mapMask.bottom : _const.mapConfigInfo.effectConfig.maskConfig.bottom.show,
        left: typeof (this.mapMask.left) !== 'undefined' ? this.mapMask.left : _const.mapConfigInfo.effectConfig.maskConfig.left.show
      }, // 地图遮罩(mask)显示设置参数，参数值为全局配置项
      mapDefaultCursor: 'default', // 地图缺省鼠标状态样式，默认为'default'
      currentBasemapType: null, // 当前底图类型参数，默认为null
      defaultBasemapsIndex: [2, 3, 4, 5], // 默认全部底图类型对应索引数组参数，默认值为[2, 3, 4, 5](2-暗色类底图，3-标准类底图，4-影像类底图，5-地形类底图)
      toolBarButtons: [
        {
          name: '测量距离',
          value: 0,
          isTooltipShow: false,
          freeze: !this.toolsBarButtonsCustomConfig[0]
        },
        {
          name: '测量面积',
          value: 1,
          isTooltipShow: false,
          freeze: !this.toolsBarButtonsCustomConfig[1]
        },
        {
          name: '圆形框选',
          value: 2,
          isTooltipShow: false,
          freeze: !this.toolsBarButtonsCustomConfig[2]
        },
        {
          name: '矩形框选',
          value: 3,
          isTooltipShow: false,
          freeze: !this.toolsBarButtonsCustomConfig[3]
        },
        {
          name: '多边形框选',
          value: 4,
          isTooltipShow: false,
          freeze: !this.toolsBarButtonsCustomConfig[4]
        },
        {
          name: '取消/清除',
          value: 5,
          isTooltipShow: false,
          freeze: !this.toolsBarButtonsCustomConfig.includes(1)
        }
      ], // 工具条按钮配置数组参数
      currentToolCommandIndex: null, // 当前工具条处于启动状态工具指令对应索引参数，默认为null
      boundsSwitchButtons: [
        {
          name: '市域',
          value: 0,
          hidden: (_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 0 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][0] === -1) || (this.boundsSwitchWidgetButtonsCustomConfig.length > 0 && this.boundsSwitchWidgetButtonsCustomConfig[0] === -1), // 根据全局配置项relationOfBoundsLayerContrastedSwitchButton，确认当前层级切换按钮显示且自定义配置按钮配置有效且配置隐藏时，为隐藏状态(即存在边界数据，但不展示按钮状态)
          freeze: !(_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 0 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][0] === 1 && this.boundsSwitchWidgetButtonsCustomConfig.length > 0 && this.boundsSwitchWidgetButtonsCustomConfig[0] === 1) // 根据全局配置项relationOfBoundsLayerContrastedSwitchButton，确认当前层级切换按钮显示且自定义配置按钮配置有效且配置显示时，为激活状态
        },
        {
          name: '片区',
          value: 1,
          hidden: (_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 1 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][1] === -1) || (this.boundsSwitchWidgetButtonsCustomConfig.length > 1 && this.boundsSwitchWidgetButtonsCustomConfig[1] === -1),
          freeze: !(_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 1 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][1] === 1 && this.boundsSwitchWidgetButtonsCustomConfig.length > 1 && this.boundsSwitchWidgetButtonsCustomConfig[1] === 1)
        },
        {
          name: '区县(市)',
          value: 2,
          hidden: (_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 2 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][2] === -1) || (this.boundsSwitchWidgetButtonsCustomConfig.length > 2 && this.boundsSwitchWidgetButtonsCustomConfig[2] === -1),
          freeze: !(_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 2 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][2] === 1 && this.boundsSwitchWidgetButtonsCustomConfig.length > 2 && this.boundsSwitchWidgetButtonsCustomConfig[2] === 1)
        },
        {
          name: '镇(乡)街',
          value: 3,
          hidden: (_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 3 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][3] === -1) || (this.boundsSwitchWidgetButtonsCustomConfig.length > 3 && this.boundsSwitchWidgetButtonsCustomConfig[3] === -1),
          freeze: !(_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 3 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][3] === 1 && this.boundsSwitchWidgetButtonsCustomConfig.length > 3 && this.boundsSwitchWidgetButtonsCustomConfig[3] === 1)
        },
        {
          name: '村社区',
          value: 4,
          hidden: (_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 4 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][4] === -1) || (this.boundsSwitchWidgetButtonsCustomConfig.length > 4 && this.boundsSwitchWidgetButtonsCustomConfig[4] === -1),
          freeze: !(_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 4 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][4] === 1 && this.boundsSwitchWidgetButtonsCustomConfig.length > 4 && this.boundsSwitchWidgetButtonsCustomConfig[4] === 1)
        },
        {
          name: '网格',
          value: 5,
          hidden: (_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 5 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][5] === -1) || (this.boundsSwitchWidgetButtonsCustomConfig.length > 5 && this.boundsSwitchWidgetButtonsCustomConfig[5] === -1),
          freeze: !(_const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton.length > this.boundsSeries && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries].length > 5 && _const.mapConfigInfo.boundsServiceConfig.relationOfBoundsLayerContrastedSwitchButton[this.boundsSeries][5] === 1 && this.boundsSwitchWidgetButtonsCustomConfig.length > 5 && this.boundsSwitchWidgetButtonsCustomConfig[5] === 1)
        }
      ], // 边界切换按钮配置数组参数
      boundsSwitchWidgetOpenStatus: null, // 边界切换微件按钮打开状态，默认为null
      currentShowBoundsLevel: this.defaultShowBoundsLevel, // 当前展示的边界层级
      isBoundsInitLoadComplete: false, // 边界初始化加载完成标识参数，默认为false
      boundsShowStatus: true, // 边界展示状态，默认为true
      boundsDisplayRelevantDefaultConfig: {
        isInteractive: true, // 显式交互性展示(控制鼠标样式动态切换实现)，默认为true
        opacity: 0.3, // 不透明度，默认为0.3
        fill: true, // 是否填充，默认为true
        color: '#2ce4fa', // 填充颜色，默认为'#2ce4fa'
        outline: true, // 是否描边，默认为true
        outlineColor: '#2ce4fa', // 描边颜色，默认为'#2ce4fa'
        outlineOpacity: 1, // 描边不透明度，默认为1
        outlineWidth: 2, // 描边宽度值，默认为2
        note: {
          show: true, // 是否展示，默认为true
          level: 15, // 开始展示层级，默认为15
          field: 'name', // 数据来源字段，默认为'name'
          opacity: 1, // 不透明度，默认为1
          fontSize: 15, // 字体尺寸，默认为15
          fontFamily: '微软雅黑', // 字体，默认为微软雅黑，可选值为微软雅黑、宋体、楷体、隶书、黑体等
          color: '#ffffff' // 颜色，默认为'#ffffff'
        } // 标注相关属性配置
      }, // 边界显示相关默认配置参数，仅对加载json类型数据时生效
      locationbarValues: {}, // 状态栏状态展示数值对象参数
      POIIcon: {},
      dataLoading: false, // 数据加载状态参数
      dataLoadingMultiprocessingController: {
        dynamicAddPOILayerProcess: false
      }, // 数据加载状态多进程控制器，默认包含动态添加POI图层(dynamicAddPOILayer)进程控制开关(默认为关)
      mouseWheelEventTriggerCallbackTimer: null, // 鼠标滚轮滚动事件触发回调定时器，默认为null(由于无法监听鼠标滚轮滚动停止事件，故通过设置定时器，变相实现监听滚轮滚动停止事件，进行回调)
      mouseWheelEventTriggerCallbackTimerCountdown: 400, // 鼠标滚轮滚动事件触发回调定时器倒计时时长(单位为ms)，默认为400
      mouseClickEventOnPOILayerTriggerCallbackFlag: false // POI图层鼠标点击事件触发回调标识，默认为false(由于存在偶发的点击POI图层所属POI，无法触发事件回调的问题，故通过设置标识，配合map事件clickGraphic使用，进行补充触发)
    }
  },
  mounted() {
    // cesium配置
    const mapOptions = {
      scene: {
        sceneMode: this.mapMode === 0 ? Cesium.SceneMode.SCENE2D : this.mapMode === 1 ? Cesium.SceneMode.COLUMBUS_VIEW : Cesium.SceneMode.SCENE3D,
        scene3DOnly: false,
        center: {
          lat: this.mapView.lat || this.mapView.lat === 0 ? this.mapView.lat : 0,
          lng: this.mapView.lng || this.mapView.lng === 0 ? this.mapView.lng : 0,
          alt: this.mapView.alt || this.mapView.alt === 0 ? this.mapView.alt : 500000,
          heading: this.mapView.heading || this.mapView.heading === 0 ? this.mapView.heading : 0,
          pitch: this.mapView.pitch || this.mapView.pitch === 0 ? this.mapView.pitch : 0,
          roll: this.mapView.roll || this.mapView.roll === 0 ? this.mapView.roll : 0
        },
        contextOptions: {
          webgl: {
            alpha: true, // div允许透明
            antialias: true // 开启抗锯齿
          }
        },
        targetFrameRate: 60, // 设置最大频率数
        requestRenderMode: _const.mapConfigInfo.mapWith3DAttributeConfig.requestRenderMode,
        maximumRenderTimeChange: 0,
        removeDblClick: true, // 移除Cesium默认的双击事件
        showSun: false, // 不显示太阳
        showMoon: false, // 不显示月亮
        showSkyBox: false, // 不显示天空盒
        showSkyAtmosphere: false, // 不显示地球大气层外光圈
        fog: false, // 不启用雾化效果
        fxaa: true, // 开启快速抗锯齿
        highDynamicRange: false, // 关闭高动态范围渲染
        globe: {
          baseColor: _const.mapConfigInfo.mapWith3DAttributeConfig.globe.baseColor,
          tileCacheSize: _const.mapConfigInfo.mapWith3DAttributeConfig.globe.tileCacheSize // 预加载瓦片数量
        },
        cameraController: {
          minimumZoomDistance: this.mapCameraZoom.minZoom, // 最小视高
          maximumZoomDistance: this.mapCameraZoom.maxZoom // 最大视高
        }
      },
      templateValues: {
        show: false
      },
      control: {
        animation: false,
        timeline: false,
        infoBox: false,
        geocoder: false,
        selectionIndicator: false,
        contextmenu: {
          hasDefault: false
        },
        mouseDownView: {
          rightDrag: false
        }
      },
      basemaps: []
    }
    this.initMap(mapOptions) // 地图初始化
  },
  beforeDestroy() {
    // 注销并销毁定时器
    if (this.mouseWheelEventTriggerCallbackTimer) {
      // 鼠标滚轮滚动事件触发回调定时器实例对象
      clearTimeout(this.mouseWheelEventTriggerCallbackTimer)
      this.mouseWheelEventTriggerCallbackTimer = null
    }
    // 销毁全部cesium实例对象
    if (this.boundsLayer) {
      // 边界图层实例对象
      this.boundsLayer.remove(true)
      this.boundsLayer = null
    }
    if (this.boundsTagLayer) {
      // 边界标注图层实例对象
      this.boundsTagLayer.remove(true)
      this.boundsTagLayer = null
    }
    if (this.measure) {
      // 测量实例对象
      this.measure.remove(true)
      this.measure = null
    }
    if (this.businessLayers) {
      for (let index in this.businessLayers) {
        // 遍历移除业务数据图层
        for (let subIndex in this.businessLayers[index]) {
          this.businessLayers[index][subIndex].remove(true)
          this.businessLayers[index][subIndex] = null
        }
      }
      this.businessLayers = {}
    }
    if (this.map.graphicLayer) {
      // 地图内部图层对象
      this.map.graphicLayer.clear()
    }
    if (this.map) {
      // 地图容器实例对象
      this.intensiveMapDestroy()
    }
  },
  computed: {
    // 动态计算地图遮罩(mask)样式
    mapMaskConfigStyle: function() {
      return {
        '--loadingColor': _const.mapConfigInfo.effectConfig.maskConfig.loading.color,
        '--topWidth': _const.mapConfigInfo.effectConfig.maskConfig.top.width,
        '--topHeight': _const.mapConfigInfo.effectConfig.maskConfig.top.height,
        '--topColor': _const.mapConfigInfo.effectConfig.maskConfig.top.color,
        '--rightWidth': _const.mapConfigInfo.effectConfig.maskConfig.right.width,
        '--rightHeight': _const.mapConfigInfo.effectConfig.maskConfig.right.height,
        '--rightColor': _const.mapConfigInfo.effectConfig.maskConfig.right.color,
        '--bottomWidth': _const.mapConfigInfo.effectConfig.maskConfig.bottom.width,
        '--bottomHeight': _const.mapConfigInfo.effectConfig.maskConfig.bottom.height,
        '--bottomColor': _const.mapConfigInfo.effectConfig.maskConfig.bottom.color,
        '--leftWidth': _const.mapConfigInfo.effectConfig.maskConfig.left.width,
        '--leftHeight': _const.mapConfigInfo.effectConfig.maskConfig.left.height,
        '--leftColor': _const.mapConfigInfo.effectConfig.maskConfig.left.color
      }
    },
    // 动态计算地图部件四周空隙留白(padding)样式
    mapComponentPaddingConfigStyle: function() {
      return {
        '--paddingTop': _const.mapConfigInfo.effectConfig.componentPaddingConfig.top,
        '--paddingRight': _const.mapConfigInfo.effectConfig.componentPaddingConfig.right,
        '--paddingBottom': _const.mapConfigInfo.effectConfig.componentPaddingConfig.bottom,
        '--paddingLeft': _const.mapConfigInfo.effectConfig.componentPaddingConfig.left
      }
    },
    // 动态计算地图部件尺寸缩放比例
    mapComponentSizeScale: function() {
      const scale = componentSizeScale(this.mapOriginalDesignSize.width, this.mapOriginalDesignSize.height)
      return {
        '--scaleX': scale.scaleX,
        '--scaleY': scale.scaleY,
        '--scaleRelative': scale.scaleRelative,
        '--scaleFontRelative': scale.scaleFontRelative
      }
    },
    // 动态计算地图popup展示类型
    mapPopupShowType: function() {
      const defaultType = 1 // 缺省展示类型，默认为1
      const configType = _const.mapConfigInfo.effectConfig.popupConfig.type
      return !isNaN(parseFloat(configType)) && isFinite(configType) && configType !== 0 ? configType : defaultType
    },
    // 动态计算地图地图popup展示参数及样式
    mapPopupConfig: function() {
      const defaultConfig = {
        // 展示类型1对应的默认参数
        1: {
          defaultHeight: 400, // popup初始默认高度值，当前默认值为400
          maxHeight: 1300, // popup最大高度值，当前默认值为1300
          thresholdOfContentFromBottom: 340, // popup内容部分距底高度计算阈值，当前默认值为340(取值与当前展示形式连线样式相关，需同步修改)
          contentHeightProportion: 0.94, // popup内容部分高度与popup容器占比率值，当前默认值为0.94(取值与背景图片具体布局相关，若图片调整需同步修改)
          contentMarginTopProportion: 0.035, // popup内容部分上部margin与popup容器占比率值，当前默认值为0.035(取值与背景图片具体布局相关，若图片调整需同步修改)
          contentMarginBottomProportion: 0.025, // popup内容部分下部margin与popup容器占比率值，当前默认值为0.025(取值与背景图片具体布局相关，若图片调整需同步修改)
          titleHeight: 89, // popup内容标题部分(文字和分隔线)高度，当前默认值为89(取值与.map-popup-type-1=>.content-container=>.content=>.title样式line-height属性(86px)和border-bottom属性(3px)取值相关，需同步修改)
          indexHeight: 201, // popup内容指标部分高度(指标为空时的缺省高度)，当前默认值为201
          // popup内容指标部分外观参数
          index: {
            labelFontSize: 28, // 指标项名称字体尺寸，当前值为28
            subLabelFontSize: 24, // 指标项辅助补充说明名称字体尺寸，当前值为24
            descriptionLineHeight: 60, // 指标项描述行高，当前默认值为60
            descriptionFontSize: 33, // 指标项描述字体尺寸，当前默认值为33
            pictureMaxShowNUmber: 4, // 指标项描述图片最大展示数量，当前默认值为4，最少为1
            pictureHeight: 100, // 指标项描述图片显示高度，当前默认值为100
            pictureHorizontalSpacing: 20, // 指标项描述图片水平间距，当前默认值为20
            pictureVerticalSpacing: 15 // 指标项描述图片竖直间距，当前默认值为20
          },
          // popup内容按钮部分外观参数
          button: {
            buttonRelatedFontSize: 28, // 按钮相关的文字字体尺寸，当前值为28
            aggregatedButtonRowHeight: 68, // 聚合类按钮行高度，当前默认值为68(取值与.map-popup-type-1=>.content-container=>.content=>.description=>.aggregated-button-container样式相关属性取值相关，需同步修改)
            singleButtonRowLimit: 3, // 单体类按钮行数量限制，当前默认值为3(取值与.map-popup-type-1=>.content-container=>.content=>.description=>.button-container=>.operate-button:nth-child(3n+2)样式相关，需同步修改)
            singleButtonRowHeight: 80 // 单体类按钮行高度，当前默认值为80(取值与.map-popup-type-1=>.content-container=>.content=>.description=>.button-container=>.operate-button样式相关属性取值相关，需同步修改)
          },
          pagerHeight: 50 // popup内容页码部分高度，当前默认值为50(取值需与.map-popup-type-1=>.content-container=>.content=>.pager-container样式height属性取值保持一致，需同步修改)
        },
        // 展示类型2对应的默认参数
        2: {
          defaultHeight: 400, // popup初始默认高度值，当前默认值为400
          maxHeight: 700, // popup最大高度值，当前默认值为700
          thresholdOfContentFromBottom: 400, // popup内容部分距底高度计算阈值，当前默认值为400(取值与当前展示形式连线样式相关，需同步修改)
          contentHeightProportion: 1, // popup内容部分高度与popup容器占比率值，当前默认值为1(当前图片为分体图片，此项数值为1)
          contentMarginTopProportion: 0, // popup内容部分上部margin与popup容器占比率值，当前默认值为0(当前图片为分体图片，此项数值为0)
          contentMarginBottomProportion: 0, // popup内容部分下部margin与popup容器占比率值，当前默认值为0(当前图片为分体图片，此项数值为0)
          titleHeight: 84, // popup内容标题部分(文字和分隔线)高度，当前默认值为84(取值与.map-popup-type-2=>.content-container=>.content=>.title样式line-height属性(84px)和border-bottom属性(0px)取值相关，需同步修改)
          indexHeight: 201, // popup内容指标部分高度(指标为空时的缺省高度)，当前默认值为201
          // popup内容指标部分外观参数
          index: {
            labelFontSize: 28, // 指标项名称字体尺寸，当前值为28
            subLabelFontSize: 24, // 指标项辅助补充说明名称字体尺寸，当前值为24
            descriptionLineHeight: 60, // 指标项描述行高，当前默认值为60
            descriptionFontSize: 33, // 指标项描述字体尺寸，当前默认值为33
            pictureMaxShowNUmber: 4, // 指标项描述图片最大展示数量，当前默认值为4，最少为1
            pictureHeight: 100, // 指标项描述图片显示高度，当前默认值为100
            pictureHorizontalSpacing: 20, // 指标项描述图片水平间距，当前默认值为20
            pictureVerticalSpacing: 15 // 指标项描述图片竖直间距，当前默认值为15
          },
          // popup内容按钮部分外观参数
          button: {
            buttonRelatedFontSize: 28, // 按钮相关的文字字体尺寸，当前值为28
            aggregatedButtonRowHeight: 68, // 聚合类按钮行高度，当前默认值为68(取值与.map-popup-type-2=>.content-container=>.content=>.description=>.aggregated-button-container样式相关属性取值相关，需同步修改)
            singleButtonRowLimit: 3, // 单体类按钮行数量限制，当前默认值为3(取值与.map-popup-type-2=>.content-container=>.content=>.description=>.button-container=>.operate-button:nth-child(3n+2)样式相关，需同步修改)
            singleButtonRowHeight: 80 // 单体类按钮行高度，当前默认值为80(取值与.map-popup-type-2=>.content-container=>.content=>.description=>.button-container=>.operate-button样式相关属性取值相关，需同步修改)
          },
          pagerHeight: 50 // popup内容页码部分高度，当前默认值为50(取值需与.map-popup-type-2=>.content-container=>.content=>.pager-container样式height属性取值保持一致，需同步修改)
        },
        // 展示类型3对应的默认参数
        3: {
          defaultHeight: 400, // popup初始默认高度值，当前默认值为400
          maxHeight: 700, // popup最大高度值，当前默认值为700
          thresholdOfContentFromBottom: 400, // popup内容部分距底高度计算阈值，当前默认值为400(取值与当前展示形式连线样式相关，需同步修改)
          contentHeightProportion: 1, // popup内容部分高度与popup容器占比率值，当前默认值为1(当前图片为分体图片，此项数值为1)
          contentMarginTopProportion: 0, // popup内容部分上部margin与popup容器占比率值，当前默值为0(当前图片为分体图片，此项数值为0)
          contentMarginBottomProportion: 0, // popup内容部分下部margin与popup容器占比率值，当前默认值为0(当前图片为分体图片，此项数值为0)
          titleHeight: 84, // popup内容标题部分(文字和分隔线)高度，当前默认值为84(取值与.map-popup-type-3=>.content-container=>.content=>.title样式line-height属性(84px)和border-bottom属性(0px)取值相关，需同步修改)
          indexHeight: 201, // popup内容指标部分高度(指标为空时的缺省高度)，当前默认值为201
          // popup内容指标部分外观参数
          index: {
            labelFontSize: 42, // 指标项名称字体尺寸，当前值为42
            subLabelFontSize: 33, // 指标项辅助补充说明名称字体尺寸，当前值为33
            descriptionLineHeight: 60, // 指标项描述行高，当前默认值为60
            descriptionFontSize: 35, // 指标项描述字体尺寸，当前默认值为35
            pictureMaxShowNUmber: 4, // 指标项描述图片最大展示数量，当前默认值为4，最少为1
            pictureHeight: 120, // 指标项描述图片显示高度，当前默认值为120
            pictureHorizontalSpacing: 20, // 指标项描述图片水平间距，当前默认值为20
            pictureVerticalSpacing: 15 // 指标项描述图片竖直间距，当前默认值为15
          },
          // popup内容按钮部分外观参数
          button: {
            buttonRelatedFontSize: 35, // 按钮相关的文字字体尺寸，当前值为35
            aggregatedButtonRowHeight: 68, // 聚合类按钮行高度，当前默认值为68(取值与.map-popup-type-3=>.content-container=>.content=>.description=>.aggregated-button-container样式相关属性取值相关，需同步修改)
            singleButtonRowLimit: 3, // 单体类按钮行数量限制，当前默认值为3(取值与.map-popup-type-3=>.content-container=>.content=>.description=>.button-container=>.operate-button:nth-child(3n+2)样式相关，需同步修改)
            singleButtonRowHeight: 80 // 单体类按钮行高度，当前默认值为80(取值与.map-popup-type-3=>.content-container=>.content=>.description=>.button-container=>.operate-button样式相关属性取值相关，需同步修改)
          },
          pagerHeight: 50 // popup内容页码部分高度，当前默认值为50(取值需与.map-popup-type-3=>.content-container=>.content=>.pager-container样式height属性取值保持一致，需同步修改)
        }
      }
      const indexWidth = _const.mapConfigInfo.effectConfig.popupConfig.width - _const.mapConfigInfo.effectConfig.popupConfig.margin.right - _const.mapConfigInfo.effectConfig.popupConfig.margin.left // 计算配置的popup内容指标部分宽度值
      // 根据地图popup展示类型，动态配置popup相关计算样式参数
      const currentConfig = {
        defaultHeight: defaultConfig[this.mapPopupShowType].defaultHeight, // popup计算初始默认高度值
        maxHeight: defaultConfig[this.mapPopupShowType].maxHeight, // popup计算最大高度值
        thresholdOfContentFromBottom: defaultConfig[this.mapPopupShowType].thresholdOfContentFromBottom, // popup内容部分距底高度计算阈值
        bottom: defaultConfig[this.mapPopupShowType].thresholdOfContentFromBottom - defaultConfig[this.mapPopupShowType].defaultHeight, // popup内容部分计算距底高度
        contentHeightProportion: defaultConfig[this.mapPopupShowType].contentHeightProportion, // popup内容部分高度与popup容器占比率值
        contentMarginTopProportion: defaultConfig[this.mapPopupShowType].contentMarginTopProportion, // popup内容部分上部margin与popup容器占比率值
        contentMarginBottomProportion: defaultConfig[this.mapPopupShowType].contentMarginBottomProportion, // popup内容部分下部margin与popup容器占比率值
        titleHeight: defaultConfig[this.mapPopupShowType].titleHeight, // popup内容标题部分计算(文字和分隔线)高度
        indexHeight: defaultConfig[this.mapPopupShowType].indexHeight, // popup内容指标部分计算高度(指标为空时的缺省高度)
        // popup内容指标部分外观计算参数
        index: {
          width: indexWidth, // 指标项计算宽度
          labelFontSize: defaultConfig[this.mapPopupShowType].index.labelFontSize, // 指标项名称计算字体尺寸
          subLabelFontSize: defaultConfig[this.mapPopupShowType].index.subLabelFontSize, // 指标项辅助补充说明名称字体尺寸
          descriptionLineHeight: defaultConfig[this.mapPopupShowType].index.descriptionLineHeight, // 指标项描述计算行高
          descriptionFontSize: defaultConfig[this.mapPopupShowType].index.descriptionFontSize, // 指标项描述计算字体尺寸
          pictureMaxShowNUmber: defaultConfig[this.mapPopupShowType].index.pictureMaxShowNUmber, // 指标项描述图片计算最大展示数量
          pictureWidth: (indexWidth - defaultConfig[this.mapPopupShowType].index.pictureHorizontalSpacing * (defaultConfig[this.mapPopupShowType].index.pictureMaxShowNUmber - 1)) / defaultConfig[this.mapPopupShowType].index.pictureMaxShowNUmber, // 指标项描述图片计算宽度(计算公式：(popup内容指标部分宽度值-图片间距*(图片最大展示数量-1))/图片最大展示数量)
          pictureHeight: defaultConfig[this.mapPopupShowType].index.pictureHeight, // 指标项描述图片计算高度
          pictureMarginRight: defaultConfig[this.mapPopupShowType].index.pictureHorizontalSpacing, // 指标项描述图片计算右边距
          pictureMarginBottom: defaultConfig[this.mapPopupShowType].index.pictureVerticalSpacing // 指标项描述图片计算下边距
        },
        // popup内容按钮部分外观计算参数
        button: {
          isAggregatedButtonShow: _const.mapConfigInfo.effectConfig.popupConfig.button.isAggregatedButtonShow, // 聚合类按钮纳入计算标识(即聚合类按钮展示标识)
          aggregatedButtonRowHeight: defaultConfig[this.mapPopupShowType].button.aggregatedButtonRowHeight, // 聚合类按钮行计算高度
          isSingleButtonShow: _const.mapConfigInfo.effectConfig.popupConfig.button.isSingleButtonShow, // 单体类按钮纳入计算标识(即单体类按钮展示标识)
          singleButtonRowLimit: defaultConfig[this.mapPopupShowType].button.singleButtonRowLimit, // 单体类按钮行数量限制
          singleButtonRowHeight: defaultConfig[this.mapPopupShowType].button.singleButtonRowHeight // 单体类按钮行计算高度
        },
        pagerHeight: defaultConfig[this.mapPopupShowType].pagerHeight // popup内容页码部分计算高度
      }
      let currentSingleButtonWidth = 0 // 定义当前单体类按钮行按钮宽度，默认值为0
      if (currentConfig.button.singleButtonRowLimit > 0) {
        // 若当前单体类按钮行数量限制值大于0个时(即存在单体类按钮),计算更新当前单体类按钮行按钮宽度
        const singleButtonMargin = (_const.mapConfigInfo.effectConfig.popupConfig.button.singleButtonMargin.right + _const.mapConfigInfo.effectConfig.popupConfig.button.singleButtonMargin.left) / 2 * (currentConfig.button.singleButtonRowLimit - 1) // 计算单体按钮行按钮间距的总和(计算公式：(右间距+左间距)/2*(单体类按钮行数量限制值-1))
        currentSingleButtonWidth = (indexWidth - singleButtonMargin) / currentConfig.button.singleButtonRowLimit // 计算更新按钮宽度
      }
      // 动态配置popup相关样式属性
      const currentConfigStyle = {
        '--popupWidth': `${_const.mapConfigInfo.effectConfig.popupConfig.width}px`,
        '--popupHeight': `${currentConfig.defaultHeight}px`,
        '--popupBottom': `${currentConfig.bottom}px`,
        '--popupMarginTop': `${currentConfig.defaultHeight * currentConfig.contentMarginTopProportion}px`,
        '--popupMarginRight': `${_const.mapConfigInfo.effectConfig.popupConfig.margin.right}px`,
        '--popupMarginBottom': `${currentConfig.defaultHeight * currentConfig.contentMarginBottomProportion}px`,
        '--popupMarginLeft': `${_const.mapConfigInfo.effectConfig.popupConfig.margin.left}px`,
        '--titleHeight': `${currentConfig.titleHeight}px`,
        '--indexLabelFontSize': `${currentConfig.index.labelFontSize}px`,
        '--indexSubLabelFontSize': `${currentConfig.index.subLabelFontSize}px`,
        '--indexDescriptionLineHeight': `${currentConfig.index.descriptionLineHeight}px`,
        '--indexDescriptionFontSize': `${currentConfig.index.descriptionFontSize}px`,
        '--indexPictureWidth': `${currentConfig.index.pictureWidth}px`,
        '--indexPictureHeight': `${currentConfig.index.pictureHeight}px`,
        '--indexPictureMarginRight': `${currentConfig.index.pictureMarginRight}px`,
        '--indexPictureMarginBottom': `${currentConfig.index.pictureMarginBottom}px`,
        '--buttonRelatedFontSize': `${defaultConfig[this.mapPopupShowType].button.buttonRelatedFontSize}px`,
        '--singleButtonWidth': `${currentSingleButtonWidth}px`,
        '--singleButtonMarginRight': `${_const.mapConfigInfo.effectConfig.popupConfig.button.singleButtonMargin.right}px`,
        '--singleButtonMarginLeft': `${_const.mapConfigInfo.effectConfig.popupConfig.button.singleButtonMargin.left}px`,
        '--pagerHeight': `${currentConfig.pagerHeight}px`
      }
      return { currentConfig, currentConfigStyle }
    },
    // 动态计算当前网络环境下对应的全部底图类型对应索引数组
    basemapsIndex: function() {
      const currentMapServiceCustomConfig = _const.mapConfigInfo.basemapConfig.mapServiceConfig[getCurrentNetworkSituation() === 1 ? 'mapServiceInGovernmentExtranet' : 'mapServiceInInternet'] // 根据当前网络环境获取对应的地图底图自定义配置
      const currentBasemapsIndex = []
      for (let key in currentMapServiceCustomConfig) {
        if (currentMapServiceCustomConfig[key].enable) currentBasemapsIndex.push(currentMapServiceCustomConfig[key].value)
      }
      return currentBasemapsIndex
    },
    // 动态计算当前网络环境下对应的全部底图类型对应名称的对象参数
    basemapsName: function() {
      const currentMapServiceCustomConfig = _const.mapConfigInfo.basemapConfig.mapServiceConfig[getCurrentNetworkSituation() === 1 ? 'mapServiceInGovernmentExtranet' : 'mapServiceInInternet'] // 根据当前网络环境获取对应的地图底图自定义配置
      const currentBasemapsName = {}
      for (let key in currentMapServiceCustomConfig) {
        if (currentMapServiceCustomConfig[key].enable) currentBasemapsName[currentMapServiceCustomConfig[key].value] = currentMapServiceCustomConfig[key].name
      }
      return currentBasemapsName
    },
    // 动态计算右上区域微件集合样式相关配置
    mapWidgetDomainOnTopRightCssConfig: function() {
      const widgetCurrentStatus = [
        this.isShowBoundsSwitchWidget && this.currentActiveBoundsSwitchButtons.length,
        this.isShowBasemapSelectWidget && this.basemapsIndex.length,
        this.isShowToolsBar && this.currentActiveToolBarButtons.length,
        this.isShowRestoreInitialStatusWidget
      ] // 枚举当前包含微件展示控制参数
      const simpleWidgetWidth = 101 * this.mapComponentSizeScale['--scaleX'] // 单个微件宽度常量值，默认为101*缩放比例(--scaleX)
      const spacingInWidgets = 24 * this.mapComponentSizeScale['--scaleY'] // 微件间间距常量值，默认为24*缩放比例(--scaleY)
      let currentAvailableWidgetSummary = 0
      for (const item of widgetCurrentStatus) {
        if (item) currentAvailableWidgetSummary++
      }
      let calculatedWidth = 0
      if (currentAvailableWidgetSummary) {
        // 当前存在微件时，计算宽度值(计算公式：宽度常量值x微件数量+微件间距常量值x(微件数量-1))
        calculatedWidth = simpleWidgetWidth * currentAvailableWidgetSummary + spacingInWidgets * (currentAvailableWidgetSummary - 1)
      }
      return {
        value: {
          width: calculatedWidth,
          spacing: spacingInWidgets
        },
        cssValue: {
          '--spacing': `${spacingInWidgets}px`
        },
        style: {
          width: `${calculatedWidth}px`
        }
      }
    },
    // 动态计算当前处于激活状态的测量&圈画框选工具条按钮组
    currentActiveToolBarButtons: function() {
      return this.toolBarButtons.filter(item => {
        return !item.freeze
      })
    },
    // 动态计算当前处于激活状态的边界切换按钮组
    currentActiveBoundsSwitchButtons: function() {
      // 在边界切换按钮组中未处于活动状态的按钮添加新的编号，以便按钮与实际全局配置的边界图层信息建立正确关联关系
      let currentActiveBoundsSwitchButtonIndex = 0
      this.boundsSwitchButtons.forEach(item => {
        if (!item.freeze) {
          item.realValue = currentActiveBoundsSwitchButtonIndex
          currentActiveBoundsSwitchButtonIndex++
        } else if (item.hidden) currentActiveBoundsSwitchButtonIndex++
      })
      return this.boundsSwitchButtons.filter(item => {
        return !item.freeze
      })
    },
    // 动态计算当前选中的边界切换按钮(获取属性值value)
    currentSelectedBoundsSwitchButton: function() {
      let returnFlag = -1
      const selectedBoundsSwitchButton = this.currentActiveBoundsSwitchButtons.filter(item => { return item.realValue === this.currentShowBoundsLevel })
      if (selectedBoundsSwitchButton.length) returnFlag = selectedBoundsSwitchButton[0].value
      return returnFlag
    }
  },
  methods: {
    initMap(mapOptions) {
      this.map = new mars3d.Map('map-container', mapOptions)
      this.map.changeMouseModel(true) // 使用滚轮长按缩放
      this.map.fixedLight = true // 固定光照，避免模型随时间存在的亮度不一致问题
      this.map.on(mars3d.EventType.renderError, () => {
        window.location.reload()
      }) // webGL引擎崩溃自刷新
      this.mapChangeController(this.showMapType) // 加载底图
      this.initBusinessLayers() // 初始化业务图层组
      this.initMapEvent() // 地图事件监听初始化
      this.initMeasure() // 地图测量工具初始化
      this.updateLocationbarValues() // 初始化更新状态栏状态数值
      this.$emit('loaded') // 抛出加载完成事件
    },
    // 初始化业务图层组
    initBusinessLayers() {
      this.businessLayers = {
        additionalBasemapLayer: {},
        POILayer: {},
        dataLayer: {}
      }
    },
    initMapEvent() {
      // 瓦片加载进度事件监听
      this.map.on('tileLoadProgress', count => {
        const tileLoadIndex = Number(count) // 获取当前加载瓦片索引数值
        const tileIndexOfStartLoadBounds = _const.mapConfigInfo.interactConfig.tileLoadProgressCriticalValue * this.mapComponentSizeScale['--scaleRelative'] // 设定开始加载边界图层的瓦片索引临界值，当前配置值为全局配置项*相对缩放系数
        if (!this.isBoundsInitLoadComplete && tileLoadIndex >= tileIndexOfStartLoadBounds) {
          // 满足：1.边界加载未初始化，2.当前加载瓦片索引数值不小于设定开始加载边界图层的瓦片索引临界值，进行边界初始化加载
          this.boundsLoadController(this.currentShowBoundsLevel, true)
        }
      })
      // 左键单击地图空白（未单击到矢量或模型数据）时鼠标事件监听
      this.map.on('clickMap', () => {
        this.$eventBus.$emit('clickMap') // 事件发射
      })
      // 左键单击到矢量或模型数据时鼠标事件监听
      this.map.on('clickGraphic', event => {
        // 单独处理POI图层点击事件
        if (event.layer.name && event.layer.name.match('POILayer') !== null) {
          // 根据全局点击事件触发回调标识参数(mouseClickEventOnPOILayerTriggerCallbackFlag)取值(POI图层对应点击事件回调先于此事件回调)，进行后续处理
          if (this.mouseClickEventOnPOILayerTriggerCallbackFlag) {
            // 若全局点击事件触发回调标识参数(mouseClickEventOnPOILayerTriggerCallbackFlag)取值为true，则说明POI图层点击事件回调已经触发，无需再次补充触发，更新全局参数，结束
            this.mouseClickEventOnPOILayerTriggerCallbackFlag = false
            return
          }
          this.$eventBus.$emit('POILayerClick', event) // (补充)点击事件发射
        }
      })
      // popup打开事件监听
      this.map.on('popupOpen', () => {
        this.$eventBus.$emit('popupOpen') // 事件发射
      })
      // popup关闭事件监听
      this.map.on('popupClose', event => {
        this.$eventBus.$emit('popupClose', event) // 事件发射
      })
      // 相机视角移动结束事件监听
      this.map.on('cameraMoveEnd', () => {
        if (this.mouseWheelEventTriggerCallbackTimer) {
          // 当鼠标滚轮滚动事件触发回调定时器存在时，进行注销，参数重置
          clearTimeout(this.mouseWheelEventTriggerCallbackTimer)
          this.mouseWheelEventTriggerCallbackTimer = null
        }
        this.mapCameraViewChangeResponder() // 触发地图相机姿态变化响应器响应
      })
      if (this.mapMode) {
        // 在非2D平面模式下，设定额外的鼠标动作监听，变相修正相机视角移动监听偶然不触发的问题
        // 鼠标左键按下后释放事件监听
        this.map.on('leftUp', () => {
          this.mapCameraViewChangeResponder() // 触发地图相机姿态变化响应器响应
        })
        // 鼠标滚轮滚动事件监听
        this.map.on('wheel', () => {
          if (this.mouseWheelEventTriggerCallbackTimer) clearTimeout(this.mouseWheelEventTriggerCallbackTimer) // 当专用定时器存在时，进行注销
          this.mouseWheelEventTriggerCallbackTimer = setTimeout(() => {
            this.mapCameraViewChangeResponder() // 触发地图相机姿态变化响应器响应
          }, this.mouseWheelEventTriggerCallbackTimerCountdown) // 专用定时器实例化
        })
      }
    },
    // 初始化测量工具
    initMeasure() {
      this.measure = new mars3d.thing.Measure({
        label: {
          color: '#ffffff',
          font_size: 32,
          background: false
        }
      })
      this.map.addThing(this.measure)
    },
    // 地图相机姿态变化响应器
    mapCameraViewChangeResponder() {
      const currentCameraView = this.map.getCameraView() // 获取当前相机位置(视角姿态)
      const prevCameraView = this.locationbarValues.cameraView // 获取上一时相相机位置(视角姿态)(通过读取全局参数locationbarValues实现)
      if (!currentCameraView || !prevCameraView) return
      if (currentCameraView.lng === prevCameraView.lng && currentCameraView.lat === prevCameraView.lat && currentCameraView.alt === prevCameraView.alt) return // 判断对比两种时相相机位置(视角姿态)(经度、纬度、高度取值是否完全相同)，确定是否终止逻辑
      this.updateLocationbarValues() // 更新状态栏状态数值
      this.updateStatusOfBoundaryTagFromJson() // 若边界使用json展示加载，动态控制标注显隐
      this.$eventBus.$emit('mapMoveOrZoomEnd') // 地图移动或缩放结束事件发射
    },
    // 更新状态栏状态数值
    updateLocationbarValues() {
      // 为状态栏数值对象参数获取更新赋值
      this.locationbarValues = {
        level: this.map.level,
        longitude: this.map.getCameraView()?.lng,
        latitude: this.map.getCameraView()?.lat,
        cameraView: this.map.getCameraView()
      }
    },
    // 更新json数据源的边界图层的标注显隐状态
    updateStatusOfBoundaryTagFromJson() {
      if (this.boundsLayer && this.isBoundsInitLoadComplete && _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['type'] === 'json' && (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.show ?? this.boundsDisplayRelevantDefaultConfig.note.show)) {
        this.boundsLayer.setOptions({
          symbol: {
            callback: (attr, styleOption) => {
              return {
                label: {
                  opacity: styleOption.opacity && this.map.level > (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.level ?? this.boundsDisplayRelevantDefaultConfig.note.level) ? (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.opacity ?? this.boundsDisplayRelevantDefaultConfig.note.opacity) : 0
                }
              }
            }
          }
        })
      }
    },
    // 切换地图状态
    // mapStatusTYpe默认为0，可用值：0-地图初始状态(姿态)，1-中国范围状态(姿态)，2-指定地图位置状态
    switchMapStatus(mapStatusTYpe = 0, mapStatusParam = {}) {
      const latLngBufferCalculationLevelCoefficient = mapStatusParam.alt ? this.map.level : this.defaultLevelWithSwitchMapStatus
      const latBuffer = mapStatusParam.latBuffer || `${_const.mapConfigInfo.interactConfig.popupAvoidObstructBuffer.lat * Math.pow(2, (_const.mapConfigInfo.basicConfig.maxZoom - latLngBufferCalculationLevelCoefficient))}`
      const lngBuffer = mapStatusParam.lngBuffer || `${_const.mapConfigInfo.interactConfig.popupAvoidObstructBuffer.lng * Math.pow(2, (_const.mapConfigInfo.basicConfig.maxZoom - latLngBufferCalculationLevelCoefficient))}`
      const lat = Number(latBuffer) + Number(mapStatusParam.lat)
      const lng = Number(lngBuffer) + Number(mapStatusParam.lng)
      let value = {}
      switch (mapStatusTYpe) {
        case 1:
          value = { ...this.mapView, ...{ lat: 36.04713, lng: 103.035099, alt: 13106058 }} // 中国范围状态(姿态)参数
          break
        case 2:
          if (lat && lng && this.checkLatlng(lat, 'lat') && this.checkLatlng(lng, 'lng')) {
            value = { ...this.mapView, ...{ lat: lat, lng: lng, alt: mapStatusParam.alt ? mapStatusParam.alt : this.convertZoomToAltitude(this.defaultLevelWithSwitchMapStatus) }} // 指定地图位置状态(姿态)参数
          } else {
            this.$message.warning('位置信息异常，请检查！')
            return -1
          }
          break
        default:
          value = this.mapView
          break
      }
      const cameraView = this.map.getCameraView() // 获取当前相机位置(视角姿态)
      const centerView = this.map.getCenter() // 获取当前地图中心位置(视角)
      if (!cameraView || !centerView) return 0
      // 由于相机姿态属性pitch存在，会导致相机位置与地图中心位置并不总是重合，故需特别计算经度和纬度对应的相对缓冲值，用于由地图中心位置向相机位置的转换
      const lngBufferByPitch = (cameraView.lng - centerView.lng) * (value.alt / cameraView.alt) // 根据当前相机位置以及当前地图中心位置，计算相机位置经度相对缓冲值
      const latBufferByPitch = (cameraView.lat - centerView.lat) * (value.alt / cameraView.alt) // // 根据当前相机位置以及当前地图中心位置，计算相机位置纬度相对缓冲值
      const updateCameraView = { ...cameraView, ...{ lng: value.lng + lngBufferByPitch, lat: value.lat + latBufferByPitch, alt: value.alt }} // 重新整合更新的相机位置(视角姿态)参数
      this.map.setCameraView(updateCameraView, {
        duration: 0.2,
        complete: () => {
          this.mapCameraViewChangeResponder() // 回调地图相机姿态变化响应器响应
        }
      })
      return 1
    },
    // 底图切换控制器
    mapChangeController(type) {
      if (!this.map) return
      if (type === this.currentBasemapType) return
      if (!this.basemapsIndex.length) return
      if (getCurrentNetworkSituation() === 1 && type > 20) type = Math.trunc(type / 10) // 当前网络环境状况为内网(政务外网等)且传参数值大于20(即使用互联网环境地图服务类型)时，进行地图服务类型参数退化(根据配置规则，同类型地图服务参数具备数量级关系，故使用数量级换算取整的方式，进行处理)
      if (!this.basemapsIndex.includes(type)) type = this.basemapsIndex[0] // 传参不合法时，使用配置底图索引第一项作为当前选中的底图
      this.currentBasemapType = type
      if (this.map.getBasemaps().length) {
        for (const layer of this.map.getBasemaps()) this.map.removeLayer(layer, true) // 存在底图配置时，循环进行移除
      }
      this.map.setBasemapsOptions(this.basemapsDynamicGenerator(type)) // 设置更新底图资源
      setTimeout(() => {
        if (this.boundsLayer && this.boundsLayer.reload) this.boundsLayer.reload() // 延时进行边界图层重绘(若打开),避免底图重建导致的遮挡不可见
      }, 800)
    },
    // 地图底图资源动态生成器
    basemapsDynamicGenerator(type) {
      let basemaps = []
      // 根据当前网络环境动态生成底图资源
      if (getCurrentNetworkSituation() === 1) {
        // 当前网络环境状况为内网(政务外网等)时，动态生成内网地图底图资源
        // 内网地图服务默认配置
        const localnetMapServiceDefaultConfig = {
          // 天地图山东暗色地图服务
          darkModeOfTianDiTuForShanDongProvince: {
            name: '天地图山东暗色地图服务',
            serviceConfig: {
              url: 'http://59.206.217.36/tileservice/dsfg_asdxb',
              token: '5cf3cea80e7cd1f8ded32a78740e1dcc' // 烟台城市大脑项目key
            }
          },
          // 天地图中国标准改暗色地图服务(实质为天地图中国标准地图服务)
          darkenModeByStandardOfTianDiTuForCountry: {
            name: '天地图中国标准改暗色地图服务',
            serviceConfig: {
              url: {
                image: 'http://59.255.48.160:81/DataServer?T=vec_c&x={x}&y={y}&l={z}',
                note: 'http://59.255.48.160:81/DataServer?T=cva_c&x={x}&y={y}&l={z}'
              },
              option: {
                image: {
                  invertColor: true,
                  filterColor: '#4e70a6',
                  brightness: 0.6,
                  contrast: 1.8,
                  gamma: 0.3,
                  hue: 1,
                  saturation: 0
                },
                note: {
                  invertColor: true,
                  filterColor: '#4e70a6',
                  brightness: 0.6,
                  contrast: 1.8,
                  gamma: 0.3,
                  hue: 1,
                  saturation: 0
                }
              }
            }
          },
          // 天地图中国标准地图服务
          standardModeOfTianDiTuForCountry: {
            name: '天地图中国标准地图服务',
            serviceConfig: {
              url: {
                image: 'http://59.255.48.160:81/DataServer?T=vec_c&x={x}&y={y}&l={z}',
                note: 'http://59.255.48.160:81/DataServer?T=cva_c&x={x}&y={y}&l={z}'
              }
            }
          },
          // 天地图中国影像地图服务
          satelliteImageryModeOfTianDiTuForCountry: {
            name: '天地图中国影像地图服务',
            serviceConfig: {
              url: {
                image: 'http://59.255.48.160:81/DataServer?T=img_c&x={x}&y={y}&l={z}',
                note: 'http://59.255.48.160:81/DataServer?T=cia_c&x={x}&y={y}&l={z}'
              }
            }
          },
          // 天地图中国地形地图服务
          terrainModeOfTianDiTuForCountry: {
            name: '天地图中国地形地图服务',
            serviceConfig: {
              url: {
                image: 'http://59.255.48.160:81/DataServer?T=ter_c&x={x}&y={y}&l={z}',
                note: 'http://59.255.48.160:81/DataServer?T=cta_c&x={x}&y={y}&l={z}'
              }
            }
          }
        }
        const localnetMapServiceFinalConfig = deepMergeObject(localnetMapServiceDefaultConfig, _const.mapConfigInfo.basemapConfig.mapServiceConfig.mapServiceInGovernmentExtranet) // 默认配置与自定义配置合并
        // 生成底图资源
        basemaps = [
          // 天地图山东暗色地图服务
          {
            id: localnetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince?.value || 2,
            pid: 2,
            name: localnetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince.name,
            type: 'wmts',
            url: localnetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince.serviceConfig.url,
            queryParameters: {
              tk: localnetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince.serviceConfig.token
            },
            layer: 'SDRasterPubMapDJ',
            style: 'default',
            tileMatrixSetID: 'default028mm',
            format: 'image/png',
            tilingScheme: new Cesium.GeographicTilingScheme(),
            minimumLevel: 1,
            maximumLevel: 17,
            tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
            getCapabilities: false,
            enablePickFeatures: false,
            show: type === (localnetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince?.value || 2)
          },
          // 天地图中国标准改暗色地图服务
          {
            id: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry?.value || 20,
            pid: 2,
            name: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17,
                invertColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.invertColor,
                filterColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.filterColor,
                brightness: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.brightness,
                contrast: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.contrast,
                gamma: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.gamma,
                hue: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.hue,
                saturation: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.saturation
              },
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17,
                invertColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.invertColor,
                filterColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.filterColor,
                brightness: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.brightness,
                contrast: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.contrast,
                gamma: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.gamma,
                hue: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.hue,
                saturation: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.saturation
              }
            ] : [
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17,
                invertColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.invertColor,
                filterColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.filterColor,
                brightness: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.brightness,
                contrast: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.contrast,
                gamma: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.gamma,
                hue: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.hue,
                saturation: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.saturation
              },
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17,
                invertColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.invertColor,
                filterColor: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.filterColor,
                brightness: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.brightness,
                contrast: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.contrast,
                gamma: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.gamma,
                hue: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.hue,
                saturation: localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.saturation
              }
            ],
            show: type === (localnetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry?.value || 20)
          },
          // 天地图中国标准地图服务
          {
            id: localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry?.value || 3,
            pid: 2,
            name: localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              },
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              }
            ] : [
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              },
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              }
            ],
            show: type === (localnetMapServiceFinalConfig.standardModeOfTianDiTuForCountry?.value || 3)
          },
          // 天地图中国影像地图服务
          {
            id: localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry?.value || 4,
            pid: 2,
            name: localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              },
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              }
            ] : [
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              },
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                minimumLevel: 1,
                maximumLevel: 17
              }
            ],
            show: type === (localnetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry?.value || 4)
          },
          // 天地图中国地形地图服务
          {
            id: localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry?.value || 5,
            pid: 2,
            name: localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                maximumLevel: 13
              },
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                maximumLevel: 13
              }
            ] : [
              {
                name: '注记',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.note,
                crs: 'EPSG:4490',
                maximumLevel: 13
              },
              {
                name: '底图',
                type: 'xyz',
                url: localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.image,
                crs: 'EPSG:4490',
                maximumLevel: 13
              }
            ],
            show: type === (localnetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry?.value || 5)
          }
        ]
      } else {
        // 当前网络环境状况为互联网时，动态生成互联网地图底图资源
        // 互联网地图服务默认配置
        const internetMapServiceDefaultConfig = {
          // 天地图山东暗色地图服务
          darkModeOfTianDiTuForShanDongProvince: {
            name: '天地图山东暗色地图服务',
            serviceConfig: {
              url: 'http://service.sdmap.gov.cn/tileservice/dsfg_asdxb',
              token: '91525d268c7500ee280b1883546bd89f'
            }
          },
          // 天地图中国标准改暗色地图服务(实质为天地图中国标准地图服务)
          darkenModeByStandardOfTianDiTuForCountry: {
            name: '天地图中国标准改暗色地图服务',
            serviceConfig: {
              url: {
                image: 'https://{s}.tianditu.gov.cn/vec_c/wmts', // 底图服务url(经纬度投影)
                note: 'https://{s}.tianditu.gov.cn/cva_c/wmts' // 注记服务url(经纬度投影)
              },
              subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], // 子域设置
              token: {
                image: '5e5949f7e96e8a136ef36a6594f18cdf', // tk
                note: 'bcc62222fc634ec736589c483de933e6' // tk
              },
              option: {
                image: {
                  invertColor: true,
                  filterColor: '#4e70a6',
                  brightness: 0.6,
                  contrast: 1.8,
                  gamma: 0.3,
                  hue: 1,
                  saturation: 0
                },
                note: {
                  invertColor: true,
                  filterColor: '#4e70a6',
                  brightness: 0.6,
                  contrast: 1.8,
                  gamma: 0.3,
                  hue: 1,
                  saturation: 0
                }
              }
            }
          },
          // 智图暗色地图服务
          darkModeOfGeoQ: {
            name: '智图暗色地图服务',
            serviceConfig: {
              url: 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            }
          },
          // 高德标准地图改暗色地图(实质为高德标准地图服务)
          darkenModeByStandardOfGaoDe: {
            name: '高德标准地图改暗色地图',
            serviceConfig: {
              url: 'https://{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
              subdomains: ['webrd01', 'webrd02', 'webrd03', 'webrd04'], // 子域设置
              option: {
                invertColor: true,
                filterColor: '#4e70a6',
                brightness: 0.6,
                contrast: 1.8,
                gamma: 0.3,
                hue: 1,
                saturation: 0
              }
            }
          },
          // 天地图中国标准地图服务
          standardModeOfTianDiTuForCountry: {
            name: '天地图中国标准地图服务',
            serviceConfig: {
              url: {
                image: 'https://{s}.tianditu.gov.cn/vec_c/wmts', // 底图服务url(经纬度投影)
                note: 'https://{s}.tianditu.gov.cn/cva_c/wmts' // 注记服务url(经纬度投影)
              },
              subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], // 子域设置
              token: {
                image: '5e5949f7e96e8a136ef36a6594f18cdf', // tk
                note: 'bcc62222fc634ec736589c483de933e6' // tk
              }
            }
          },
          // 天地图山东标准地图服务
          standardModeOfTianDiTuForShanDongProvince: {
            name: '天地图山东标准地图服务',
            serviceConfig: {
              url: 'http://service.sdmap.gov.cn/tileservice/sdpubmap',
              token: '91525d268c7500ee280b1883546bd89f' // tk
            }
          },
          // 高德标准地图服务
          standardModeOfGaoDe: {
            name: '高德标准地图服务',
            serviceConfig: {
              url: 'https://{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
              subdomains: ['webrd01', 'webrd02', 'webrd03', 'webrd04'] // 子域设置
            }
          },
          // 天地图中国影像地图服务
          satelliteImageryModeOfTianDiTuForCountry: {
            name: '天地图中国影像地图服务',
            serviceConfig: {
              url: {
                image: 'https://{s}.tianditu.gov.cn/img_c/wmts', // 底图服务url(经纬度投影)
                note: 'https://{s}.tianditu.gov.cn/cia_c/wmts' // 注记服务url(经纬度投影)
              },
              subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], // 子域设置
              token: {
                image: '5e5949f7e96e8a136ef36a6594f18cdf', // tk
                note: 'bcc62222fc634ec736589c483de933e6' // tk
              }
            }
          },
          // 天地图山东影像地图服务
          satelliteImageryModeOfTianDiTuForShanDongProvince: {
            name: '天地图山东影像地图服务',
            serviceConfig: {
              url: {
                image: 'http://service.sdmap.gov.cn/tileservice/sdrasterpubmap', // 底图服务url
                note: 'http://service.sdmap.gov.cn/tileservice/sdrasterpubmapdj' // 注记服务url
              },
              token: {
                image: '91525d268c7500ee280b1883546bd89f', // tk
                note: '91525d268c7500ee280b1883546bd89f' // tk
              }
            }
          },
          // 高德影像地图服务
          satelliteImageryModeOfGaoDe: {
            name: '高德影像地图服务',
            serviceConfig: {
              url: {
                image: 'https://{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=6', // 底图服务url
                note: 'https://{s}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8' // 注记服务url
              },
              subdomains: ['webst01', 'webst02', 'webst03', 'webst04'] // 子域设置
            }
          },
          // 星图地球影像地图服务
          satelliteImageryModeOfGeovisEarth: {
            name: '星图地球影像地图服务',
            serviceConfig: {
              url: {
                image: 'https://{s}.geovisearth.com/base/v1/img/{z}/{x}/{y}', // 底图服务url(经纬度投影)
                note: 'https://{s}.geovisearth.com/base/v1/cia/{z}/{x}/{y}' // 注记服务url(经纬度投影)
              },
              subdomains: ['tiles1', 'tiles2', 'tiles3'], // 子域设置
              token: {
                image: 'd6654b3199fe725e1a6207d17b222c661aae2af6a956281175853083b141dab6', // tk
                note: 'd6654b3199fe725e1a6207d17b222c661aae2af6a956281175853083b141dab6' // tk
              }
            }
          },
          // 天地图中国地形地图服务
          terrainModeOfTianDiTuForCountry: {
            name: '天地图中国地形地图服务',
            serviceConfig: {
              url: {
                image: 'https://{s}.tianditu.gov.cn/ter_c/wmts', // 底图服务url(经纬度投影)
                note: 'https://{s}.tianditu.gov.cn/cta_c/wmts' // 注记服务url(经纬度投影)
              },
              subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'], // 子域设置
              token: {
                image: '5e5949f7e96e8a136ef36a6594f18cdf', // tk
                note: 'bcc62222fc634ec736589c483de933e6' // tk
              }
            }
          }
        }
        const internetMapServiceFinalConfig = deepMergeObject(internetMapServiceDefaultConfig, _const.mapConfigInfo.basemapConfig.mapServiceConfig.mapServiceInInternet) // 默认配置与自定义配置合并
        // 生成底图资源
        basemaps = [
          // 天地图山东暗色地图服务
          {
            id: internetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince?.value || 2,
            pid: 1,
            name: internetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince.name,
            type: 'wmts',
            url: internetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince.serviceConfig.url,
            queryParameters: {
              tk: internetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince.serviceConfig.token
            },
            layer: 'dsfg_asdxb',
            style: 'default',
            tileMatrixSetID: 'vector',
            format: 'image/jpeg',
            tilingScheme: new Cesium.GeographicTilingScheme(),
            minimumLevel: 1,
            maximumLevel: 17,
            tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
            getCapabilities: false,
            enablePickFeatures: false,
            show: type === (internetMapServiceFinalConfig.darkModeOfTianDiTuForShanDongProvince?.value || 2)
          },
          // 天地图中国标准改暗色地图服务
          {
            id: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry?.value || 20,
            pid: 1,
            name: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'vec',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false,
                invertColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.invertColor,
                filterColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.filterColor,
                brightness: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.brightness,
                contrast: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.contrast,
                gamma: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.gamma,
                hue: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.hue,
                saturation: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.saturation
              },
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cva',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false,
                invertColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.invertColor,
                filterColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.filterColor,
                brightness: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.brightness,
                contrast: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.contrast,
                gamma: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.gamma,
                hue: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.hue,
                saturation: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.saturation
              }
            ] : [
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cva',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false,
                invertColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.invertColor,
                filterColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.filterColor,
                brightness: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.brightness,
                contrast: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.contrast,
                gamma: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.gamma,
                hue: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.hue,
                saturation: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.note.saturation
              },
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'vec',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false,
                invertColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.invertColor,
                filterColor: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.filterColor,
                brightness: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.brightness,
                contrast: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.contrast,
                gamma: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.gamma,
                hue: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.hue,
                saturation: internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry.serviceConfig.option.image.saturation
              }
            ],
            show: type === (internetMapServiceFinalConfig.darkenModeByStandardOfTianDiTuForCountry?.value || 20)
          },
          // 智图暗色地图服务
          {
            id: internetMapServiceFinalConfig.darkModeOfGeoQ?.value || 21,
            pid: 1,
            name: internetMapServiceFinalConfig.darkModeOfGeoQ.name,
            type: 'xyz',
            url: internetMapServiceFinalConfig.darkModeOfGeoQ.serviceConfig.url,
            chinaCRS: 'GCJ02',
            maximumLevel: 16,
            enablePickFeatures: false,
            show: type === (internetMapServiceFinalConfig.darkModeOfGeoQ?.value || 21)
          },
          // 高德标准地图改暗色地图
          {
            id: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe?.value || 22,
            pid: 1,
            name: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.name,
            type: 'xyz',
            url: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.url,
            subdomains: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.subdomains,
            maximumLevel: 18,
            enablePickFeatures: false,
            chinaCRS: 'GCJ02',
            invertColor: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.invertColor,
            filterColor: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.filterColor,
            brightness: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.brightness,
            contrast: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.contrast,
            gamma: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.gamma,
            hue: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.hue,
            saturation: internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe.serviceConfig.option.saturation,
            show: type === (internetMapServiceFinalConfig.darkenModeByStandardOfGaoDe?.value || 22)
          },
          // 天地图中国标准地图服务
          {
            id: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry?.value || 3,
            pid: 1,
            name: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'vec',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cva',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ] : [
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cva',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'vec',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ],
            show: type === (internetMapServiceFinalConfig.standardModeOfTianDiTuForCountry?.value || 3)
          },
          // 天地图山东标准地图服务
          {
            id: internetMapServiceFinalConfig.standardModeOfTianDiTuForShanDongProvince?.value || 31,
            pid: 1,
            name: internetMapServiceFinalConfig.standardModeOfTianDiTuForShanDongProvince.name,
            type: 'wmts',
            url: internetMapServiceFinalConfig.standardModeOfTianDiTuForShanDongProvince.serviceConfig.url,
            queryParameters: {
              tk: internetMapServiceFinalConfig.standardModeOfTianDiTuForShanDongProvince.serviceConfig.token
            },
            layer: 'SDPubMap',
            style: 'default',
            tileMatrixSetID: 'default028mm',
            format: 'image/png',
            tilingScheme: new Cesium.GeographicTilingScheme(),
            minimumLevel: 6,
            maximumLevel: 17,
            tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
            getCapabilities: false,
            enablePickFeatures: false,
            show: type === (internetMapServiceFinalConfig.standardModeOfTianDiTuForShanDongProvince?.value || 31)
          },
          // 高德标准地图服务
          {
            id: internetMapServiceFinalConfig.standardModeOfGaoDe?.value || 32,
            pid: 1,
            name: internetMapServiceFinalConfig.standardModeOfGaoDe.name,
            type: 'xyz',
            url: internetMapServiceFinalConfig.standardModeOfGaoDe.serviceConfig.url,
            subdomains: internetMapServiceFinalConfig.standardModeOfGaoDe.serviceConfig.subdomains,
            maximumLevel: 18,
            enablePickFeatures: false,
            chinaCRS: 'GCJ02',
            show: type === (internetMapServiceFinalConfig.standardModeOfGaoDe?.value || 32)
          },
          // 天地图中国影像地图服务
          {
            id: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry?.value || 4,
            pid: 1,
            name: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'img',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cia',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ] : [
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cia',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'img',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ],
            show: type === (internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForCountry?.value || 4)
          },
          // 天地图山东影像地图服务
          {
            id: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince?.value || 41,
            pid: 1,
            name: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.url.image,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.token.image
                },
                layer: 'SDRasterPubMap',
                style: 'default',
                tileMatrixSetID: 'default028mm',
                format: 'image/png',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 6,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.url.note,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.token.note
                },
                layer: 'SDRasterPubMapDJ',
                style: 'default',
                tileMatrixSetID: 'default028mm',
                format: 'image/png',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 6,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ] : [
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.url.note,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.token.note
                },
                layer: 'SDRasterPubMapDJ',
                style: 'default',
                tileMatrixSetID: 'default028mm',
                format: 'image/png',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 6,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.url.image,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince.serviceConfig.token.image
                },
                layer: 'SDRasterPubMap',
                style: 'default',
                tileMatrixSetID: 'default028mm',
                format: 'image/png',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 6,
                maximumLevel: 17,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ],
            show: type === (internetMapServiceFinalConfig.satelliteImageryModeOfTianDiTuForShanDongProvince?.value || 41)
          },
          // 高德影像地图服务
          {
            id: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe?.value || 42,
            pid: 1,
            name: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.subdomains,
                maximumLevel: 18,
                enablePickFeatures: false,
                chinaCRS: 'GCJ02'
              },
              {
                name: '标注',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.subdomains,
                maximumLevel: 18,
                enablePickFeatures: false,
                chinaCRS: 'GCJ02'
              }
            ] : [
              {
                name: '标注',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.subdomains,
                maximumLevel: 18,
                enablePickFeatures: false,
                chinaCRS: 'GCJ02'
              },
              {
                name: '底图',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe.serviceConfig.subdomains,
                maximumLevel: 18,
                enablePickFeatures: false,
                chinaCRS: 'GCJ02'
              }
            ],
            show: type === (internetMapServiceFinalConfig.satelliteImageryModeOfGaoDe?.value || 42)
          },
          // 星图地球影像地图服务
          {
            id: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth?.value || 43,
            pid: 1,
            name: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.subdomains,
                queryParameters: {
                  token: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.token.image
                },
                maximumLevel: 18,
                enablePickFeatures: false
              },
              {
                name: '标注',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.subdomains,
                queryParameters: {
                  token: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.token.note
                },
                maximumLevel: 18,
                enablePickFeatures: false
              }
            ] : [
              {
                name: '标注',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.subdomains,
                queryParameters: {
                  token: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.token.note
                },
                maximumLevel: 18,
                enablePickFeatures: false
              },
              {
                name: '底图',
                type: 'xyz',
                url: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.subdomains,
                queryParameters: {
                  token: internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth.serviceConfig.token.image
                },
                maximumLevel: 18,
                enablePickFeatures: false
              }
            ],
            show: type === (internetMapServiceFinalConfig.satelliteImageryModeOfGeovisEarth?.value || 43)
          },
          // 天地图中国地形地图服务
          {
            id: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry?.value || 5,
            pid: 1,
            name: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.name,
            type: 'group',
            layers: !_const.mapConfigInfo.basemapConfig.multiLayerStackingOrder ? [
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'ter',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 13,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cta',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 13,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ] : [
              {
                name: '注记',
                type: 'wmts',
                url: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.note,
                subdomains: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.token.note
                },
                layer: 'cta',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 13,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              },
              {
                name: '底图',
                type: 'wmts',
                url: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.url.image,
                subdomains: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.subdomains,
                queryParameters: {
                  tk: internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry.serviceConfig.token.image
                },
                layer: 'ter',
                style: 'default',
                tileMatrixSetID: 'c',
                format: 'tiles',
                tilingScheme: new Cesium.GeographicTilingScheme(),
                minimumLevel: 1,
                maximumLevel: 13,
                tileMatrixLabels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18'],
                getCapabilities: false,
                enablePickFeatures: false
              }
            ],
            show: type === (internetMapServiceFinalConfig.terrainModeOfTianDiTuForCountry?.value || 5)
          }
        ]
      }
      return basemaps
    },
    // 边界加载控制器
    // level可选值:-1-不显示边界、其他正整数值-根据全局配置项mapConfigInfo.boundsServiceConfig.boundsLayerInfo数组参数情况确定
    boundsLoadController(level, isInit = false, isShow = false, isForceReload = false, wmsCql) {
      if (isInit) {
        if (!this.isBoundsInitLoadComplete) this.isBoundsInitLoadComplete = true // 初始加载时(level为null或-1时为隐式初始化)设置标识参数为true
        if (level === null || level === -1) return // 隐式初始化时(level为null或-1)，退出
      } else {
        if (this.currentShowBoundsLevel === level && !isShow && !isForceReload && !wmsCql) return // 边界重复加载验证
        if (!this.isBoundsInitLoadComplete) {
          // 初始加载未完成时，提示并阻止操作
          this.$message.warning('正在加载数据，请稍等！')
          return
        }
      }
      if (this.boundsLayer) {
        this.map.removeLayer(this.boundsLayer)
        this.boundsLayer = null
      }
      if (this.boundsTagLayer) {
        this.map.removeLayer(this.boundsTagLayer) // 标注信息移除
        this.boundsTagLayer = null
      }
      if (level === -1) return // 明确不展示图层时，不进行图层加载
      this.currentShowBoundsLevel = level
      this.boundsShowStatus = true // 边界展示开关设置为开
      if (_const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo.length - 1 < this.boundsSeries || _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries].length - 1 < this.currentShowBoundsLevel || Object.prototype.toString.call(_const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]) !== '[object Object]') return // 参数合法性判别
      const type = _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['type'] // 获取当前边界层级配置类型
      this.boundsDisplayRelevantDefaultConfig = deepMergeObject(this.boundsDisplayRelevantDefaultConfig, this.boundsDisplayRelevantConfig)
      // 根据边界层级配置类型，进行边界图层实例化
      let boundsLayerOption = {}
      let wmsParameters = {}
      switch (type) {
        // wms
        case 'url':
          wmsParameters = {
            transparent: true,
            format: 'image/png'
          }
          if (wmsCql) wmsParameters['cql_filter'] = wmsCql
          this.boundsLayer = new mars3d.layer.WmsLayer({
            url: _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['service'][getCurrentNetworkSituation() === 0 ? 'url' : 'urlInGovernmentExtranet'], // 未匹配到配置网络时使用互联网环境资源，匹配到配置网络时使用内网环境资源
            layers: _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel][type],
            parameters: wmsParameters
          })
          break
        // json
        case 'json':
          boundsLayerOption = {
            data: _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel][type],
            chinaCRS: _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['chinaCRS'],
            opacity: _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]?.opacity ?? 1,
            symbol: {
              styleOptions: {
                opacity: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.opacity ?? this.boundsDisplayRelevantDefaultConfig.opacity,
                fill: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.fill ?? this.boundsDisplayRelevantDefaultConfig.fill,
                color: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.color ?? this.boundsDisplayRelevantDefaultConfig.color,
                outline: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.outline ?? this.boundsDisplayRelevantDefaultConfig.outline,
                outlineStyle: {
                  color: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.outlineColor ?? this.boundsDisplayRelevantDefaultConfig.outlineColor,
                  opacity: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.outlineOpacity ?? this.boundsDisplayRelevantDefaultConfig.outlineOpacity,
                  width: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.outlineWidth ?? this.boundsDisplayRelevantDefaultConfig.outlineWidth
                }
              }
            }
          }
          // 根据图层样式styleField参数是否配置，进行图层分类样式设定
          if (_const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleField'] !== undefined) {
            boundsLayerOption.symbol.styleField = _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleField']
            let styleFieldOptions = {}
            for (let key in _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleFieldOption']) {
              const currentStyleFieldOption = {}
              // 根据配置，依次构建styleFieldOption，配置使用顺序优先级为：按边界显示层级独立配置 > 全部边界显示统一配置 > 默认配置
              currentStyleFieldOption[key] = {
                opacity: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.['styleFieldOption']?.[key]?.opacity ?? this.boundsDisplayRelevantDefaultConfig?.['styleFieldOption']?.[key]?.opacity ?? _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleFieldOption'][key].opacity,
                color: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.['styleFieldOption']?.[key]?.fillColor ?? this.boundsDisplayRelevantDefaultConfig?.['styleFieldOption']?.[key]?.fillColor ?? _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleFieldOption'][key].fillColor,
                outlineStyle: {
                  opacity: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.['styleFieldOption']?.[key]?.outlineOpacity ?? this.boundsDisplayRelevantDefaultConfig?.['styleFieldOption']?.[key]?.outlineOpacity ?? _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleFieldOption'][key].outlineOpacity,
                  color: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.['styleFieldOption']?.[key]?.outlineColor ?? this.boundsDisplayRelevantDefaultConfig?.['styleFieldOption']?.[key]?.outlineColor ?? _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleFieldOption'][key].outlineColor
                },
                label: {
                  text: `{${this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.field ?? this.boundsDisplayRelevantDefaultConfig.note.field}}`,
                  opacity: (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.show ?? this.boundsDisplayRelevantDefaultConfig.note.show) && (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.['styleFieldOption']?.[key]?.opacity ?? this.boundsDisplayRelevantDefaultConfig?.['styleFieldOption']?.[key]?.opacity ?? _const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['styleFieldOption'][key].opacity) && this.map.level > (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.level ?? this.boundsDisplayRelevantDefaultConfig.note.level) ? (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.opacity ?? this.boundsDisplayRelevantDefaultConfig.note.opacity) : 0,
                  font_size: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.fontSize ?? this.boundsDisplayRelevantDefaultConfig.note.fontSize,
                  font_family: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.fontFamily ?? this.boundsDisplayRelevantDefaultConfig.note.fontFamily,
                  color: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.color ?? this.boundsDisplayRelevantDefaultConfig.note.color,
                  scaleByDistance: true,
                  scaleByDistance_far: 20000000,
                  scaleByDistance_farValue: 0.1,
                  scaleByDistance_near: 1000,
                  scaleByDistance_nearValue: 1
                }
              }
              styleFieldOptions = { ...styleFieldOptions, ...currentStyleFieldOption }
            }
            boundsLayerOption.symbol.styleFieldOptions = styleFieldOptions
          } else {
            // 图层样式styleField参数配置参数未设定时，根据配置，进行标注属性设定，配置使用顺序优先级为：按边界显示层级独立配置 > 全部边界显示统一配置 > 默认配置
            boundsLayerOption.symbol.styleOptions.label = {
              text: `{${this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.field ?? this.boundsDisplayRelevantDefaultConfig.note.field}}`,
              opacity: (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.show ?? this.boundsDisplayRelevantDefaultConfig.note.show) && this.map.level > (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.level ?? this.boundsDisplayRelevantDefaultConfig.note.level) ? (this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.opacity ?? this.boundsDisplayRelevantDefaultConfig.note.opacity) : 0,
              font_size: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.fontSize ?? this.boundsDisplayRelevantDefaultConfig.note.fontSize,
              font_family: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.fontFamily ?? this.boundsDisplayRelevantDefaultConfig.note.fontFamily,
              color: this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.note?.color ?? this.boundsDisplayRelevantDefaultConfig.note.color,
              scaleByDistance: true,
              scaleByDistance_far: 20000000,
              scaleByDistance_farValue: 0.1,
              scaleByDistance_near: 1000,
              scaleByDistance_nearValue: 1
            }
          }
          this.boundsLayer = new mars3d.layer.GeoJsonLayer(boundsLayerOption)
          break
      }
      this.map.addLayer(this.boundsLayer)
      // 设置图层点击事件监听事件，用于业务组件进行回调
      this.boundsLayer.on('click', event => {
        const coordinate = mars3d.LngLatPoint.fromCartesian(event.cartesian).format()
        const position = { lat: coordinate.lat, lng: coordinate.lng }
        this.$eventBus.$emit('layerClick', { level: this.currentShowBoundsLevel, position: position, event: event }) // 图层点击事件发射
        this.$eventBus.$emit('clickMap') // 地图空白点击事件发射(避免图层点击影响popup关闭)
      })
      // 当前层级配置使用json数据时，根据交互属性配置(禁止交互时)，设置鼠标(显式)交互样式为默认样式
      if (_const.mapConfigInfo.boundsServiceConfig.boundsLayerInfo[this.boundsSeries][this.currentShowBoundsLevel]['type'] === 'json' && !(this.boundsDisplayRelevantDefaultConfig?.[this.currentShowBoundsLevel]?.isInteractive ?? this.boundsDisplayRelevantDefaultConfig.isInteractive)) {
        this.boundsLayer.on('mouseOver', () => {
          this.map.setCursor(this.mapDefaultCursor)
        })
      }
      // 标注信息前置添加
      this.boundsLayer.readyPromise.then(() => {
        this.$eventBus.$emit('mapBoundsTagLayerLoadReady', { level: this.currentShowBoundsLevel }) // 标注图层加载准备完成事件发射
      })
    },
    // 边界显示隐藏开关
    boundsSwitch() {
      if (!this.isBoundsInitLoadComplete) {
        // 初始加载未完成时，提示并阻止操作
        this.$message.warning('正在加载数据，请稍等！')
        return
      }
      if (this.boundsShowStatus) {
        this.boundsLoadController(-1)
        this.boundsShowStatus = false
      } else {
        this.boundsLoadController(this.currentShowBoundsLevel, false, true)
      }
    },
    // 测量&圈画框选工具条微件tooltip控制开关
    toolsBarTooltipSwitch(buttonIndex) {
      let tooltipIndex = null
      for (let index in this.toolBarButtons) {
        if (this.toolBarButtons[index].value === buttonIndex) {
          tooltipIndex = index
          break
        }
      }
      if (tooltipIndex === null) return
      this.toolBarButtons[tooltipIndex].isTooltipShow = !this.toolBarButtons[tooltipIndex].isTooltipShow
    },
    // 测量&圈画框选工具条微件按钮指令发射器
    toolCommandLauncher(commandIndex) {
      if (!this.map || !this.measure) return
      this.currentToolCommandIndex = commandIndex // 更新当前指令索引
      // 根据指令索引，启动对应地图操作
      switch (commandIndex) {
        case 0:
          this.measureDistance() // 测量距离
          break
        case 1:
          this.measureArea() // 测量面积
          break
        case 2:
          this.selectByDrawShape(1) // 圆形框选
          break
        case 3:
          this.selectByDrawShape(2) // 矩形框选
          break
        case 4:
          this.selectByDrawShape() // 多边形框选
          break
        case 5:
          this.clearToolMarkOnMap() // 清除/取消指令
          break
      }
    },
    // 距离测量方法
    measureDistance() {
      this.measure.distance({
        showAddText: true,
        // label: {
        //   // 自定义显示label的graphic类型
        //   type: "div",
        //   updateText: function (text, graphic) {
        //     // updateText是必须，用于动态更新 text
        //     // graphic.html = `<div class="marsGreenGradientPnl" >${text}</div>`
        //   },
        //   // 下面是graphic对应类型本身的参数
        //   html: `<div class="marsGreenGradientPnl" ></div>`,
        //   horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        //   verticalOrigin: Cesium.VerticalOrigin.BOTTOM
        // }
        style: {
          color: '#ffff00',
          width: 10,
          clampToGround: false
        }
      })
    },
    // 面积测量方法
    measureArea() {
      this.measure.area({
        style: {
          color: '#00fff2',
          opacity: 0.4,
          outline: true,
          outlineColor: '#fafa5a',
          outlineWidth: 1,
          clampToGround: false
        }
      })
    },
    // 图形圈画选择方法
    selectByDrawShape(shapeIndex = 0) {
      this.clearToolMarkOnMap() // 移除圈画工具地图痕迹(若存在)
      let drawShapeType = 'polygon'
      switch (shapeIndex) {
        case 1:
          drawShapeType = 'circle'
          break
        case 2:
          drawShapeType = 'rectangle'
          break
      }
      this.map.graphicLayer.startDraw({
        type: drawShapeType,
        style: {
          color: '#00aef7',
          opacity: 0.4,
          clampToGround: true
        },
        success: graphic => {
          this.$eventBus.$emit('drawShapeOnMapCompleted', graphic) // 绘制完成事件发射
        }
      })
    },
    // 取消工具指令/清除地图上使用工具绘制产生的痕迹的方法
    clearToolMarkOnMap(forceClearFlag = false) {
      this.map.graphicLayer.clear() // 取消框选操作&清除框选绘制痕迹
      this.measure.stopDraw() // 停止测量(若启动)
      if (forceClearFlag || this.currentToolCommandIndex === 5) {
        // 传参(forceClearFlag)为true或者当前工具指令索引参数(currentToolCommandIndex)为5，认为为手动点击按钮的主动触发行为
        this.measure.clear() // 取消测量操作&清空测量绘制痕迹
        this.currentToolCommandIndex = null // 重置当前工具指令索引参数为null
      }
    },
    // 地图微件提重(避免其他组件遮挡微件)
    mapWidgetIncreaseWeight(increaseWeight) {
      this.$eventBus.$emit('subtractWeight', increaseWeight) // 降重事件发射
    },
    //  POI图层动态添加
    dynamicAddPOILayer(info = []) {
      if (JSON.stringify(this.businessLayers) === '{}') return
      let addLoadingNumber = 0
      for (const item of info) {
        // 创建POI图层
        if (!this.businessLayers.POILayer[item.id]) {
          addLoadingNumber++
          let generalIcon = defaultIcon
          if (item.layerIcon !== null) {
            generalIcon = `${window._CONFIG['domianURL']}/${item.layerIcon}`
            if (item.layerIcon.substring(0, 4) === 'http') generalIcon = `${item.layerIcon}`
          }
          this.POIIcon[item.id] = generalIcon
          this.dataLoadingMultiprocessingController.dynamicAddPOILayerProcess = true
          this.dataLoading = true
          const canvasIcon = new Image()
          canvasIcon.crossOrigin = 'Anonymous'
          canvasIcon.src = this.POIIcon[item.id]
          canvasIcon.onload = () => {
            // 图层实例化(若不存在)
            if (JSON.stringify(this.businessLayers) === '{}') return
            this.businessLayers.POILayer[item.id] = new mars3d.layer.GraphicLayer({
              name: `POILayer-${item.id}`, // 添加唯一图层(类别)名称
              id: item.id,
              pid: `${item.showMode}-${item.loadMode}`, // 根据showMode(POI图层显示模式，0为隐式展示模式，1为显式展示模式)和loadMode(POI加载模式，0为显式加载(全量加载)，1为隐式加载(按需加载))，拼接设置pid
              show: !(!item.showMode && item.loadMode), // 图层显示模式模式(showMode，0为隐式展示模式，1为显式展示模式)为隐式展示模式且图层POI加载模式(loadMode，0为显式加载(全量加载)，1为隐式加载(按需加载))为隐式加载时，图层设置为隐藏状态
              // 聚合样式配置
              clustering: {
                enabled: true,
                clampToGround: false,
                pixelRange: 5,
                getImage: count => {
                  const canvas = document.createElement('canvas')
                  canvas.width = _const.mapConfigInfo.effectConfig.poiConfig.cluster.width * 2 * this.mapComponentSizeScale['--scaleX']
                  canvas.height = (_const.mapConfigInfo.effectConfig.poiConfig.cluster.height * 2 + _const.mapConfigInfo.effectConfig.poiConfig.label.top.spacing + _const.mapConfigInfo.effectConfig.poiConfig.label.top.fontSize * 2) * this.mapComponentSizeScale['--scaleY']
                  const context2D = canvas.getContext('2d')
                  context2D.font = `${_const.mapConfigInfo.effectConfig.poiConfig.label.top.fontSize * 2 * this.mapComponentSizeScale['--scaleFontRelative']}px ${_const.mapConfigInfo.effectConfig.poiConfig.label.top.fontFamily}`
                  context2D.fillStyle = _const.mapConfigInfo.effectConfig.poiConfig.label.top.color
                  context2D.lineWidth = _const.mapConfigInfo.effectConfig.poiConfig.label.top.fontWeight === 'normal' ? 1 : 2
                  context2D.textAlign = 'center'
                  context2D.fillText(count, _const.mapConfigInfo.effectConfig.poiConfig.cluster.width * this.mapComponentSizeScale['--scaleX'], _const.mapConfigInfo.effectConfig.poiConfig.label.top.fontSize * 2 * this.mapComponentSizeScale['--scaleY'])
                  context2D.drawImage(canvasIcon, 0, (_const.mapConfigInfo.effectConfig.poiConfig.label.top.fontSize * 2 + _const.mapConfigInfo.effectConfig.poiConfig.label.top.spacing) * this.mapComponentSizeScale['--scaleY'], _const.mapConfigInfo.effectConfig.poiConfig.cluster.width * 2 * this.mapComponentSizeScale['--scaleX'], _const.mapConfigInfo.effectConfig.poiConfig.cluster.height * 2 * this.mapComponentSizeScale['--scaleY'])
                  return canvas.toDataURL('image/png')
                }
              }
            })
            this.map.addLayer(this.businessLayers.POILayer[item.id])
            this.businessLayers.POILayer[item.id].on('click', event => {
              this.mouseClickEventOnPOILayerTriggerCallbackFlag = true // 更新全局点击事件触发回调标识参数(mouseClickEventOnPOILayerTriggerCallbackFlag)为true
              this.$eventBus.$emit('POILayerClick', event) // 事件发射
            })
            addLoadingNumber--
            if (addLoadingNumber === 0) {
              this.dataLoadingMultiprocessingController.dynamicAddPOILayerProcess = false
              if (this.judgeDataLoadingMultiprocessingControllerEndState()) this.dataLoading = false
            }
          }
        }
      }
    },
    // POI图层清空
    clearPOILayer(layerId, isKeepHiddenLayer = false) {
      if (layerId && this.businessLayers.POILayer[layerId]) {
        this.businessLayers.POILayer[layerId].clear(true) // 传参时进行指定图层的清空
      } else {
        for (let index in this.businessLayers.POILayer) {
          if (isKeepHiddenLayer && !this.getPOILayerMode(index, 'show')) continue
          this.businessLayers.POILayer[index].clear(true)
        }
      }
    },
    // 获取指定POI图层指定模式的状态
    getPOILayerMode(layerId, mode) {
      let modeIndex = 0
      switch (mode) {
        case 'show':
          modeIndex = 0
          break
        case 'click':
          modeIndex = 1
          break
      }
      return this.businessLayers.POILayer[layerId].pid.split('-')[modeIndex] === '0' ? 0 : 1
    },
    // 数据图层动态添加
    dynamicAddDataLayer(layerId) {
      if (this.businessLayers.dataLayer[layerId]) this.clearDataLayer(layerId)
      this.businessLayers.dataLayer[layerId] = new mars3d.layer.GraphicLayer()
      this.map.addLayer(this.businessLayers.dataLayer[layerId])
      return this.businessLayers.dataLayer[layerId]
    },
    // 数据图层清空移除(清空)
    clearDataLayer(layerId, type = 0) {
      if (layerId) {
        if (!this.businessLayers.dataLayer[layerId]) return
        if (!type) this.businessLayers.dataLayer[layerId].clear(false) // 传两参(layerId, type)时进行指定图层的清空
        else this.businessLayers.dataLayer[layerId].remove(true) // 传一参(layerId)时进行指定图层的移除
      } else {
        // 不传参时全部移除(清空)
        for (let index in this.businessLayers.dataLayer) {
          if (!type) this.businessLayers.dataLayer[index].clear(false) // 传参(type)时进行指定图层的清空
          else this.businessLayers.dataLayer[index].remove(true) // 不传参(type)时进行指定图层的移除
        }
      }
    },
    // 额外地图底图图层动态添加
    dynamicAddAdditionalBasemapLayer(layers = []) {
      let result = []
      if (!Array.isArray(layers)) return result
      const supportedServiceType = ['WMTS'] // 支持的服务类型，目前只支持wmts，后续有需求在增加
      let currentAdditionalBaseMapLayerIndex = Object.keys(this.businessLayers.additionalBasemapLayer).length // 获取当前additionalBasemapLayer对象长度，作为后续新添加的basemap的图层实例对象的key属性
      for (const item of layers) {
        if (item?.type && supportedServiceType.includes(item.type.toUpperCase())) {
          this.businessLayers.additionalBasemapLayer[currentAdditionalBaseMapLayerIndex] = new mars3d.layer.WmtsLayer(item.option)
          this.map.addLayer(this.businessLayers.additionalBasemapLayer[currentAdditionalBaseMapLayerIndex])
          result.push(this.businessLayers.additionalBasemapLayer[currentAdditionalBaseMapLayerIndex])
          currentAdditionalBaseMapLayerIndex++
        } else continue
      }
      return result
    },
    // 判断数据加载状态多进程控制器是否处于结束状态
    judgeDataLoadingMultiprocessingControllerEndState() {
      let isClosed = true
      for (const key in this.dataLoadingMultiprocessingController) {
        if (this.dataLoadingMultiprocessingController[key]) {
          isClosed = false
          break
        }
      }
      return isClosed
    },
    // 层级转换为海拔高
    convertZoomToAltitude(zoom) {
      // 层级海拔高对照关系
      const convertRelation = {
        2: 32091612.9,
        3: 15996366.3,
        4: 7973539.4,
        5: 3974485.8,
        6: 1981119.9,
        7: 987507.8,
        8: 492232.6,
        9: 245357.9,
        10: 122301,
        11: 60962,
        12: 30387,
        13: 15146.7,
        14: 7550,
        15: 3763.2,
        16: 1875.8,
        17: 935,
        18: 466
      }
      if (!(!isNaN(parseFloat(zoom)) && isFinite(zoom)) || zoom > 18) return convertRelation[18] // 数字合法性检查未通过或层级超过18时，返回层级18对应海拔高
      if (zoom < 2) return convertRelation[2] // 层级小于2时，返回层级2对应海拔高
      return convertRelation[zoom]
    },
    // 增强版地图销毁方法
    intensiveMapDestroy() {
      // 使用context获取上下文，并进行手动调用消除，解决原有销毁方法只销毁不释放内存的问题
      let gl = this.map.scene.context._originalGLContext
      this.map.destroy()
      this.map = null
      gl.getExtension('WEBGL_lose_context').loseContext()
      gl = null
    },
    // 检查经度、纬度合法性
    checkLatlng(value, type) {
      if (type !== 'lat' && type !== 'lng') return false // 入参合法性检查
      if (!(!isNaN(parseFloat(value)) && isFinite(value))) return false // 数字合法性检查
      // 数值范围合法性检查
      const valueLimit = {
        lat: [-90, 90],
        lng: [-180, 180]
      }
      if (parseFloat(value) >= valueLimit[type][0] && parseFloat(value) <= valueLimit[type][1]) return true
      else return false
    }
  }
}
</script>

<style lang="scss" scoped>
.map-container {
  height: 100%;
  overflow: hidden;
  .loading-mask {
    width: 100%;
    height: 100%;
    position: absolute;
    background: var(--loadingColor);
    z-index: 4;
    cursor: default;
    .loading-mask-spinner {
      width: 100%;
      position: absolute;
      top: calc(50% - 55px * var(--scaleRelative));
      text-align: center;
      .circular {
        width: calc(200px * var(--scaleRelative));
        height: calc(200px * var(--scaleRelative));
        -webkit-animation: loading-rotate 2s linear infinite;
        animation: loading-rotate 2s linear infinite;
      }
      .path {
        animation: loading-dash 1.5s ease-in-out infinite;
        stroke-dasharray: 90,150;
        stroke-dashoffset: 0;
        stroke-width: 2;
        stroke: #409eff;
        stroke-linecap: round;
      }
      @keyframes loading-dash {
        0% {
          stroke-dasharray: 1,200;
          stroke-dashoffset: 0;
        }
        50% {
          stroke-dasharray: 90,150;
          stroke-dashoffset: calc(-40px * var(--scaleRelative));
        }
        100% {
          stroke-dasharray: 90,150;
          stroke-dashoffset: calc(-120px * var(--scaleRelative));
        }
      }
      @keyframes loading-rotate {
        100% {
          transform: rotate(360deg);
        }
      }
    }
  }
  .map-widget-domain-on-top-right {
    position: absolute;
    top: var(--paddingTop);
    right: calc(var(--paddingRight) + 80px * var(--scaleX));
    display: flex;
    justify-content: space-between;
    z-index: 3;
    .widget-common {
      width: calc(101px * var(--scaleX));
      height: calc(100px * var(--scaleY));
      background-size: 100% 100%;
      background-repeat: no-repeat;
      background-image: url('~@/assets/map/map-widget/common/background.png');
      .buttons-container {
        position: absolute;
        height: auto;
        top: calc(100px * var(--scaleY));
        .button-container {
          width: calc(101px * var(--scaleX));
          height: calc(100px * var(--scaleY));
          margin-top: calc(20px * var(--scaleY));
          padding-top: calc(5px * var(--scaleY));
          background-size: 100% 100%;
          background-repeat: no-repeat;
          background-image: url('~@/assets/map/map-widget/common/background.png');
          display: flex;
          justify-content: center;
          align-items: center;
          cursor: pointer;
          .tooltip-container {
            width: calc(160px * var(--scaleX));
            height: calc(50px * var(--scaleY));
            position: absolute;
            right: calc(109px * var(--scaleX));
            background-size: 100% 100%;
            background-repeat: no-repeat;
            background-image: url('~@/assets/map/map-widget/common/tooltip-background.png');
            .tooltip-content {
              width: calc(100% - 40px * var(--scaleX));
              line-height: calc(50px * var(--scaleY));
              margin-right: calc(25px * var(--scaleX));
              margin-left: calc(15px * var(--scaleX));
              text-align: center;
              color: #ffffff;
              font-size: calc(24px * var(--scaleFontRelative));
              .scroll-wrap {
                max-width: 100%;
                display: inline-block;
                overflow: hidden;
                white-space: nowrap;
              }
              .scroll-item {
                animation: scroll linear 4s alternate infinite;
                float: left;
              }
              @keyframes scroll {
                0% {
                  margin-left: 0;
                  transform: translateX(0);
                }
                10% {
                  margin-left: 0;
                  transform: translateX(0);
                }
                90% {
                  margin-left: 100%;
                  transform: translateX(-100%);
                }
                100% {
                  margin-left: 100%;
                  transform: translateX(-100%);
                }
              }
            }
          }
        }
      }
    }
    .bounds-switch-widget {
      cursor: pointer;
      .widget-icon-container {
        height: 100%;
        border-radius: calc(12px * var(--scaleRelative));
        .widget-icon {
          height: calc(26px * var(--scaleY));
          position: absolute;
          background-size: 100% 100%;
          background-repeat: no-repeat;
        }
      }
      .widget-icon-container-close {
        background: #80808080;
      }
      .buttons-container {
        display: none;
        .button-container {
          .icon {
            height: calc(26px * var(--scaleY));
            background-size: 100% 100%;
            background-repeat: no-repeat;
          }
          .tooltip-container {
            display: none;
          }
          &:hover .tooltip-container {
            display: block;
          }
          &:hover .button-icon-0 {
            width: calc(77px * var(--scaleX));
            margin: calc(40px * var(--scaleY)) calc(12px * var(--scaleX)) calc(34px * var(--scaleY));
            background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/city-active-icon.png');
          }
          &:hover .button-icon-1 {
            width: calc(51px * var(--scaleX));
            margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
            background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/area-active-icon.png');
          }
          &:hover .button-icon-2 {
            width: calc(49px * var(--scaleX));
            margin: calc(40px * var(--scaleY)) calc(26px * var(--scaleX)) calc(34px * var(--scaleY));
            background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/county-active-icon.png');
          }
          &:hover .button-icon-3 {
            width: calc(51px * var(--scaleX));
            margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
            background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/street-active-icon.png');
          }
          &:hover .button-icon-4 {
            width: calc(77px * var(--scaleX));
            margin: calc(40px * var(--scaleY)) calc(12px * var(--scaleX)) calc(34px * var(--scaleY));
            background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/village-active-icon.png');
          }
          &:hover .button-icon-5 {
            width: calc(51px * var(--scaleX));
            margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
            background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/grid-active-icon.png');
          }
        }
      }
      .button-icon-0 {
        width: calc(77px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(12px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/city-icon.png');
      }
      .button-icon-1 {
        width: calc(51px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/area-icon.png');
      }
      .button-icon-2 {
        width: calc(49px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(26px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/county-icon.png');
      }
      .button-icon-3 {
        width: calc(51px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/street-icon.png');
      }
      .button-icon-4 {
        width: calc(77px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(12px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/village-icon.png');
      }
      .button-icon-5 {
        width: calc(51px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/grid-icon.png');
      }
      .button-icon-0-selected {
        width: calc(77px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(12px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/city-active-icon.png');
      }
      .button-icon-1-selected {
        width: calc(51px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/area-active-icon.png');
      }
      .button-icon-2-selected {
        width: calc(49px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(26px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/county-active-icon.png');
      }
      .button-icon-3-selected {
        width: calc(51px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/street-active-icon.png');
      }
      .button-icon-4-selected {
        width: calc(77px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(12px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/village-active-icon.png');
      }
      .button-icon-5-selected {
        width: calc(51px * var(--scaleX));
        margin: calc(40px * var(--scaleY)) calc(25px * var(--scaleX)) calc(34px * var(--scaleY));
        background-image: url('~@/assets/map/map-widget/self-widget/bounds-switch-widget/grid-active-icon.png');
      }
      &:hover .buttons-container {
        display: block;
      }
    }
    .basemap-toggle-widget {
      .widget-icon {
        width: calc(52px * var(--scaleX));
        height: calc(52px * var(--scaleY));
        margin: calc(26.5px * var(--scaleY)) calc(24.5px * var(--scaleX)) calc(21.5px * var(--scaleY));
        background-repeat: no-repeat;
        background-size: 100% 100%;
      }
      .buttons-container {
        display: none;
        .button-container {
          .icon {
            width: calc(52px * var(--scaleX));
            height: calc(52px * var(--scaleY));
            margin: calc(26.5px * var(--scaleY)) calc(24.5px * var(--scaleX)) calc(21.5px * var(--scaleY));
            background-repeat: no-repeat;
            background-size: 100% 100%;
          }
          .tooltip-container {
            display: none;
          }
          &:hover .icon {
            width: calc(60px * var(--scaleX));
            height: calc(60px * var(--scaleY));
            margin: calc(22.5px * var(--scaleY)) calc(20.5px * var(--scaleX)) calc(17.5px * var(--scaleY));
            border: #fabe00 calc(4px * var(--scaleRelative)) solid;
            border-radius: calc(5px * var(--scaleRelative));
          }
          &:hover .tooltip-container {
            display: block;
          }
        }
      }
      &:hover .widget-icon {
        width: calc(60px * var(--scaleX));
        height: calc(60px * var(--scaleY));
        margin: calc(22.5px * var(--scaleY)) calc(20.5px * var(--scaleX)) calc(17.5px * var(--scaleY));
        border: #fabe00 calc(4px * var(--scaleRelative)) solid;
        border-radius: calc(5px * var(--scaleRelative));
      }
      &:hover .buttons-container {
        display: block;
      }
      .button-icon-2 {
        background-image: url('~@/assets/map/map-widget/self-widget/basemap-toggle-widget/dark-map-icon.png');
      }
      .button-icon-3 {
        background-image: url('~@/assets/map/map-widget/self-widget/basemap-toggle-widget/standard-map-icon.png');
      }
      .button-icon-4 {
        background-image: url('~@/assets/map/map-widget/self-widget/basemap-toggle-widget/satellite-map-icon.png');
      }
      .button-icon-5 {
        background-image: url('~@/assets/map/map-widget/self-widget/basemap-toggle-widget/terrain-map-icon.png');
      }
      .button-icon-2-selected, .button-icon-3-selected, .button-icon-4-selected, .button-icon-5-selected {
        width: calc(60px * var(--scaleX)) !important;
        height: calc(60px * var(--scaleY)) !important;
        margin: calc(22.5px * var(--scaleY)) calc(20.5px * var(--scaleX)) calc(17.5px * var(--scaleY)) !important;
        border: #fabe00 calc(4px * var(--scaleRelative)) solid;
        border-radius: calc(5px * var(--scaleRelative));
      }
    }
    .measure-and-drawing-selection-widget {
      .widget-icon {
        width: calc(52px * var(--scaleX));
        height: calc(47px * var(--scaleY));
        margin: calc(29px * var(--scaleY)) calc(24.5px * var(--scaleX)) calc(24px * var(--scaleY));
        background-size: 100% 100%;
        background-repeat: no-repeat;
        background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/widget-icon.png');
      }
      .buttons-container {
        display: none;
        .button-container {
          .button-common {
            display: flex;
          }
          .button-0 {
            .icon {
              width: calc(49px * var(--scaleX));
              height: calc(49px * var(--scaleY));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-distance-measurement-icon.png');
            }
            .tooltip-container {
              display: none;
            }
            &:hover .icon {
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-distance-measurement-active-icon.png');
            }
            &:hover .tooltip-container{
              display: block;
            }
          }
          .button-1 {
            .icon {
              width: calc(49px * var(--scaleX));
              height: calc(50px * var(--scaleY));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-area-measurement-icon.png');
            }
            .tooltip-container {
              display: none;
            }
            &:hover .icon {
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-area-measurement-active-icon.png');
            }
            &:hover .tooltip-container{
              display: block;
            }
          }
          .button-2 {
            .icon {
              width: calc(49px * var(--scaleX));
              height: calc(50px * var(--scaleY));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-drawing-circle-selection-icon.png');
            }
            .tooltip-container {
              display: none;
            }
            &:hover .icon {
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-drawing-circle-selection-active-icon.png');
            }
            &:hover .tooltip-container{
              display: block;
            }
          }
          .button-3 {
            .icon {
              width: calc(47px * var(--scaleX));
              height: calc(47px * var(--scaleY));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-drawing-rectangle-selection-icon.png');
            }
            .tooltip-container {
              display: none;
            }
            &:hover .icon {
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-drawing-rectangle-selection-active-icon.png');
            }
            &:hover .tooltip-container{
              display: block;
            }
          }
          .button-4 {
            .icon {
              width: calc(55px * var(--scaleX));
              height: calc(50px * var(--scaleY));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-drawing-polygon-selection-icon.png');
            }
            .tooltip-container {
              display: none;
            }
            &:hover .icon {
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-drawing-polygon-selection-active-icon.png');
            }
            &:hover .tooltip-container{
              display: block;
            }
          }
          .button-5 {
            .icon {
              width: calc(48px * var(--scaleX));
              height: calc(48px * var(--scaleY));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-mark-clear-icon.png');
            }
            .tooltip-container {
              display: none;
            }
            &:hover .icon {
              background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/button-mark-clear-active-icon.png');
            }
            &:hover .tooltip-container{
              display: block;
            }
          }
        }
      }
      &:hover .widget-icon {
        background-image: url('~@/assets/map/map-widget/self-widget/measure-and-drawing-selection-widget/widget-active-icon.png');
      }
      &:hover .buttons-container {
        display: block;
      }
    }
    .restore-initial-status-widget {
      cursor: pointer;
      .widget-icon {
        width: calc(52px * var(--scaleX));
        height: calc(47px * var(--scaleY));
        margin: calc(29px * var(--scaleY)) calc(24.5px * var(--scaleX)) calc(24px * var(--scaleY));
        background-size: 100% 100%;
        background-repeat: no-repeat;
        background-image: url('~@/assets/map/map-widget/self-widget/restore-initial-status-widget/widget-icon.png');
      }
    }
  }
  .location-bar-widget {
    position: absolute;
    right: var(--paddingRight);
    bottom: var(--paddingBottom);
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url('~@/assets/map/map-widget/self-widget/location-bar-widget/widget-background.png');
    z-index: 3;
    & > p {
      width: calc(640px * var(--scaleX));
      height: calc(44px * var(--scaleY));
      margin: calc(12px * var(--scaleY)) calc(24px * var(--scaleX));
      font-size: calc(28px * var(--scaleFontRelative));
      font-weight: bold;
      color: #d0deee;
      display: flex;
      align-items: center;
      justify-content: space-around;
    }
  }
}
.map-mask {
  position: absolute;
  pointer-events: none;
  z-index: 1;
}
.map-mask-top {
  width: var(--topWidth);
  height: var(--topHeight);
  top: 0;
  background: linear-gradient(0deg, #ffffff00, var(--topColor));
}
.map-mask-right {
  width: var(--rightWidth);
  height: var(--rightHeight);
  right: calc(-8px * var(--scaleX));
  background: linear-gradient(90deg, #ffffff00, var(--rightColor));
}
.map-mask-bottom {
  width: var(--bottomWidth);
  height: var(--bottomHeight);
  bottom: 0;
  background: linear-gradient(180deg, #ffffff00, var(--bottomColor));
}
.map-mask-left {
  width: var(--leftWidth);
  height: var(--leftHeight);
  left: calc(-8px * var(--scaleX));
  background: linear-gradient(-90deg, #ffffff00, var(--leftColor));
}
</style>

<style lang="scss">
.map-popup {
  .map-popup-type-1 {
    position: absolute;
    left: calc(-153px * var(--scaleX));
    bottom: calc(103px * var(--scaleY));
    .line {
      width: calc(163px * var(--scaleX));
      height: calc(369px * var(--scaleY));
      position: relative;
      background-repeat: no-repeat;
      background-size: 100% 100%;
      background-image: url('~@/assets/map/map-popup/popup-1/line.png');
      z-index: 2;
    }
    .content-container {
      width: calc(var(--popupWidth) * var(--scaleX));
      height: calc(var(--popupHeight) * var(--scaleY));
      position: inherit;
      right: calc(120px * var(--scaleX));
      bottom: calc(var(--popupBottom) * var(--scaleY));
      background-repeat: no-repeat;
      background-size: 100% 100%;
      background-image: url('~@/assets/map/map-popup/popup-1/content.png');
      cursor: default;
      .content {
        width: calc(100% - (var(--popupMarginRight) + var(--popupMarginLeft)) * var(--scaleX));
        height: calc(100% - (var(--popupMarginTop) + var(--popupMarginBottom)) * var(--scaleY));
        margin: calc(var(--popupMarginTop) * var(--scaleY)) calc(var(--popupMarginRight) * var(--scaleX)) calc(var(--popupMarginBottom) * var(--scaleY)) calc(var(--popupMarginLeft) * var(--scaleX));
        .title {
          line-height: calc(86px * var(--scaleY));
          font-size: calc(36px * var(--scaleFontRelative));
          border-bottom: #39adff66 calc(3px * var(--scaleY)) solid;
          .name {
            .scroll-wrap {
              max-width: 100%;
            }
          }
        }
        .description {
          width: calc(100% - (var(--popupMarginRight) + var(--popupMarginLeft)) * var(--scaleX));
        }
        .index-container {
          & > p {
            color: #39adff;
            & > span {
              color: #ffffff;
            }
          }
        }
        .button-container {
          .operate-button {
            line-height: calc(60px * var(--scaleY));
            background-image: url('~@/assets/map/map-popup/popup-1/button-background.png');
            &:hover {
              transform: scale(1.03);
              background-image: url('~@/assets/map/map-popup/popup-1/button-background-hover.png');
            }
          }
        }
        .pager-container {
          width: calc(100% - (var(--popupMarginRight) + var(--popupMarginLeft)) * var(--scaleX));
          bottom: calc(6px * var(--scaleY));
        }
      }
    }
  }
  .map-popup-type-2 {
    position: absolute;
    left: calc((var(--popupWidth) + 200px) * var(--scaleX));
    bottom: calc(-292px * var(--scaleY));
    .content-container {
      width: calc(var(--popupWidth) * var(--scaleX));
      height: calc(var(--popupHeight) * var(--scaleY));
      position: inherit;
      right: calc(120px * var(--scaleX));
      bottom: calc(var(--popupBottom) * var(--scaleY));
      background-repeat: no-repeat;
      background-size: 100% 100%;
      cursor: default;
      .content {
        width: 100%;
        height: calc(100% - (var(--popupMarginTop) + var(--popupMarginBottom)) * var(--scaleY));
        margin: calc(var(--popupMarginTop) * var(--scaleY)) 0 calc(var(--popupMarginBottom) * var(--scaleY)) 0;
        .title {
          line-height: calc(84px * var(--scaleY));
          margin-bottom: calc(5px * var(--scaleY));
          font-size: calc(36px * var(--scaleFontRelative));
          display: flex;
          .name {
            width: 89%;
            height: 100%;
            background-repeat: no-repeat;
            background-size: 100% 100%;
            background-image: url('~@/assets/map/map-popup/popup-2/title.png');
            .scroll-wrap {
              max-width: calc(100% - (var(--popupMarginLeft) * 2 + 11px) * var(--scaleX));
              margin: 0 calc(6px * var(--scaleX)) 0 calc((var(--popupMarginLeft) * 2 + 5px) * var(--scaleX));
            }
          }
          .button {
            width: calc(11% - 3px * var(--scaleX));
            margin-left: calc(3px * var(--scaleX));
            background-repeat: no-repeat;
            background-size: 100% 100%;
            background-image: url('~@/assets/map/map-popup/popup-2/close.png');
            cursor: pointer;
          }
        }
        .description {
          width: 100%;
          background: #0e2c50cc;
          border: #538bd0 calc(4px * var(--scaleRelative)) solid;
        }
        .index-container {
          margin: 0 calc(var(--popupMarginRight) * var(--scaleX)) 0 calc(var(--popupMarginLeft) * var(--scaleX));
          & > p {
            color: #ffffff;
            & > span {
              color: #64a8ff;
            }
          }
        }
        .aggregated-button-container {
          margin: 0 calc(var(--popupMarginRight) * var(--scaleX)) 0 calc(var(--popupMarginLeft) * var(--scaleX));
        }
        .button-container {
          .operate-button {
            line-height: calc(55px * var(--scaleY));
            background-image: url('~@/assets/map/map-popup/popup-2/button-background.png');
            &:hover {
              transform: scale(1.03);
            }
          }
        }
        .pager-container {
          width: 100%;
          bottom: 0;
          background: #0e2c50cc;
          border: #538bd0 calc(4px * var(--scaleRelative)) solid;
          border-top-width: 0;
          .fill-gap {
            width: 100%;
            height: calc(4px * var(--scaleRelative));
            position: inherit;
            top: calc(-2px * var(--scaleRelative));
            background: #354d6eb3;
          }
        }
        &:not(.has-pager) {
          .description {
            height: calc(100% - (var(--titleHeight) - 10px) * var(--scaleY)) !important;
          }
        }
      }
    }
  }
  .map-popup-type-3 {
    position: absolute;
    left: calc((var(--popupWidth) + 200px) * var(--scaleX));
    bottom: calc(-292px * var(--scaleY));
    .content-container {
      width: calc(var(--popupWidth) * var(--scaleX));
      height: calc(var(--popupHeight) * var(--scaleY));
      position: inherit;
      right: calc(120px * var(--scaleX));
      bottom: calc(var(--popupBottom) * var(--scaleY));
      background-repeat: no-repeat;
      background-size: 100% 100%;
      cursor: default;
      .content {
        width: 100%;
        height: calc(100% - (var(--popupMarginTop) + var(--popupMarginBottom)) * var(--scaleY));
        margin: calc(var(--popupMarginTop) * var(--scaleY)) 0 calc(var(--popupMarginBottom) * var(--scaleY)) 0;
        .title {
          line-height: calc(84px * var(--scaleY));
          margin-bottom: calc(9px * var(--scaleY));
          font-size: calc(46px * var(--scaleFontRelative));
          .name {
            background-repeat: no-repeat;
            background-size: 100% 100%;
            background-image: url('~@/assets/map/map-popup/popup-3/title.png');
            .scroll-wrap {
              max-width: calc(100% - (var(--popupMarginLeft) * 2 + 96px) * var(--scaleX));
              margin: 0 calc(6px * var(--scaleX)) 0 calc((var(--popupMarginLeft) * 2 + 5px) * var(--scaleX));
            }
          }
          .button {
            width: calc(50px * var(--scaleRelative));
            height: calc(50px * var(--scaleRelative));
            position: absolute;
            top: calc((96px - 50px) / 2 * var(--scaleY));
            right: calc(20px * var(--scaleX));
            background-repeat: no-repeat;
            background-size: 100% 100%;
            background-image: url('~@/assets/map/map-popup/popup-3/close.png');
            cursor: pointer;
          }
        }
        .description {
          width: 100%;
          background-image: url('~@/assets/map/map-popup/popup-3/description-background-left.png'),
          url('~@/assets/map/map-popup/popup-3/description-background-right.png'),
          linear-gradient(0deg, #132e51 0%, #132e5199 100%);
          background-position: top left, top right, center center;
          background-repeat: no-repeat, no-repeat repeat, no-repeat;
        }
        .index-container {
          margin: 0 calc(var(--popupMarginRight) * var(--scaleX)) 0 calc(var(--popupMarginLeft) * var(--scaleX));
          & > p {
            color: #ffffff;
            & > span {
              font-weight: bold;
            }
          }
        }
        .aggregated-button-container {
          margin: 0 calc(var(--popupMarginRight) * var(--scaleX)) 0 calc(var(--popupMarginLeft) * var(--scaleX));
        }
        .button-container {
          .operate-button {
            line-height: calc(55px * var(--scaleY));
            background-image: url('~@/assets/map/map-popup/popup-3/button-background.png');
            &:hover {
              background-image: url('~@/assets/map/map-popup/popup-3/button-background-hover.png');
            }
          }
        }
        .pager-container {
          width: 100%;
          bottom: 0;
          background-image: url('~@/assets/map/map-popup/popup-3/description-background-bottom.png'),
          url('~@/assets/map/map-popup/popup-3/description-background-left.png'),
          url('~@/assets/map/map-popup/popup-3/description-background-right.png'),
          linear-gradient(0deg, #132e51 0%, #132e51 100%);
          background-position: bottom center, top left, top right, center center;
          background-repeat: no-repeat, no-repeat, no-repeat repeat, no-repeat;
          .fill-gap {
            width: calc(100% - 24px * var(--scaleX));
            height: calc(4px * var(--scaleRelative));
            position: inherit;
            top: calc(-2px * var(--scaleRelative));
            background: #132e51;
          }
        }
        &:not(.has-pager) {
          .description {
            height: calc(100% - (var(--titleHeight) - 15px) * var(--scaleY)) !important;
            background-image: url('~@/assets/map/map-popup/popup-3/description-background-bottom.png'),
            url('~@/assets/map/map-popup/popup-3/description-background-left.png'),
            url('~@/assets/map/map-popup/popup-3/description-background-right.png'),
            linear-gradient(0deg, #132e51 0%, #132e5199 100%);
            background-position: bottom center, top left, top right, center center;
            background-repeat: no-repeat, no-repeat, no-repeat repeat, no-repeat;
          }
        }
      }
    }
  }
  .map-popup-type-1, .map-popup-type-2, .map-popup-type-3 {
    .content-container {
      .content {
        .title {
          font-weight: bold;
          color: #ffffff;
          .name {
            .scroll-wrap {
              display: inline-block;
              vertical-align: top;
              overflow: hidden;
              white-space: nowrap;
            }
            .scroll-item {
              animation: scroll linear 12s alternate infinite;
              float: left;
            }
            @keyframes scroll {
              0% {
                margin-left: 0;
                transform: translateX(0);
              }
              10% {
                margin-left: 0;
                transform: translateX(0);
              }
              90% {
                margin-left: 100%;
                transform: translateX(-100%);
              }
              100% {
                margin-left: 100%;
                transform: translateX(-100%);
              }
            }
          }
        }
        .description {
          position: absolute;
          .loading {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            .spinner {
              .circular {
                width: calc(110px * var(--scaleRelative));
                height: calc(110px * var(--scaleRelative));
                -webkit-animation: loading-rotate 2s linear infinite;
                animation: loading-rotate 2s linear infinite;
              }
              .path {
                animation: loading-dash 1.5s ease-in-out infinite;
                stroke-dasharray: 90,150;
                stroke-dashoffset: 0;
                stroke-width: 2;
                stroke: #409eff;
                stroke-linecap: round;
              }
              @keyframes loading-dash {
                0% {
                  stroke-dasharray: 1,200;
                  stroke-dashoffset: 0;
                }
                50% {
                  stroke-dasharray: 90,150;
                  stroke-dashoffset: calc(-40px * var(--scaleRelative));
                }
                100% {
                  stroke-dasharray: 90,150;
                  stroke-dashoffset: calc(-120px * var(--scaleRelative));
                }
              }
              @keyframes loading-rotate {
                100% {
                  transform: rotate(360deg);
                }
              }
            }
          }
          .index-container {
            overflow-y: overlay;
            & > p {
              width: 100%;
              line-height: calc(var(--indexDescriptionLineHeight) * var(--scaleY));
              font-size: calc(var(--indexDescriptionFontSize) * var(--scaleFontRelative));
              text-overflow: ellipsis;
              overflow: hidden;
              & > span {
                font-size: calc(var(--indexLabelFontSize) * var(--scaleFontRelative));
              }
              .row-a-button-common {
                float: right;
                font-size: calc(var(--indexSubLabelFontSize) * var(--scaleFontRelative));
                cursor: pointer;
                &:hover {
                  transform: scale(1.02);
                }
              }
              & > a {
                width: 100%;
                display: flex;
                & > img {
                  width: calc(var(--indexPictureWidth) * var(--scaleX));
                  height: calc(var(--indexPictureHeight) * var(--scaleY));
                  margin-right: calc(var(--indexPictureMarginRight) * var(--scaleX));
                  margin-bottom: calc(var(--indexPictureMarginBottom) * var(--scaleY));
                  cursor: pointer;
                  &:last-child {
                    margin-right: 0;
                  }
                }
              }
              .row-button-common {
                width: calc(42px * var(--scaleX));
                height: calc(42px * var(--scaleY));
                margin-left: calc(15px * var(--scaleX));
                background-repeat: no-repeat;
                background-size: 100% 100%;
                cursor: pointer;
                &:hover {
                  transform: scale(1.2);
                }
              }
              .row-button-phone {
                background-image: url('~@/assets/map/map-popup/common/row-button-icon-phone.png');
              }
            }
            .p-single-row {
              display: flex;
              align-items: center;
            }
            .p-multi-row {
              display: block;
            }
            .empty {
              display: flex;
              align-items: center;
              & > p {
                width: 100%;
                font-size: calc(var(--indexLabelFontSize) * var(--scaleFontRelative));
                color: #ffffff;
                text-align: center;
              }
            }
          }
          .aggregated-button-container {
            display: flex;
            & > span {
              width: calc(65px * var(--scaleX));
              line-height: calc(46px * var(--scaleY));
              font-size: calc(var(--buttonRelatedFontSize) * var(--scaleFontRelative));
              color: #ffffff;
              word-break: keep-all;
            }
            & > .content {
              width: calc(100% - 130px * var(--scaleX));
              height: calc(46px * var(--scaleY));
              margin: 0 calc(8px * var(--scaleX));
              background-repeat: no-repeat;
              background-size: 100% 100%;
              background-image: url('~@/assets/map/map-popup/common/aggregated-button-background.png');
              .button-plate-container {
                height: calc(24px * var(--scaleY));
                margin: calc(16px * var(--scaleY)) calc(23px * var(--scaleX)) calc(6px * var(--scaleY));
                .color-ribbon {
                  height: calc(8px * var(--scaleY));
                  margin: calc(20px * var(--scaleY)) calc(9px * var(--scaleX)) 0;
                  background: linear-gradient(90deg, #e60012 0%, #f7ab00 32.3%, #fff100 66.7%, #02f061 100%);
                }
                .button-plate {
                  height: calc(18px * var(--scaleY));
                  margin: calc(-13px * var(--scaleY)) 0 0;
                  display: flex;
                  justify-content: space-between;
                  .button-common {
                    width: calc(18px * var(--scaleX));
                    height: calc(18px * var(--scaleY));
                    background-repeat: no-repeat;
                    background-size: 100% 100%;
                    cursor: pointer;
                    z-index: 1;
                    &:hover {
                      transform: scale(1.5);
                    }
                  }
                  .button-special-1 {
                    background-image: url('~@/assets/map/map-popup/common/aggregated-button-red.png');
                  }
                  .button-special-2 {
                    background-image: url('~@/assets/map/map-popup/common/aggregated-button-orange.png');
                  }
                  .button-special-3 {
                    background-image: url('~@/assets/map/map-popup/common/aggregated-button-yellow.png');
                  }
                  .button-special-4 {
                    background-image: url('~@/assets/map/map-popup/common/aggregated-button-green.png');
                  }
                  .button-selected {
                    cursor: no-drop;
                    animation: circle-ripple 2s infinite;
                  }
                  @keyframes circle-ripple {
                    from {
                      transform: scale(1);
                    }
                    to {
                      transform: scale(1.7);
                    }
                  }
                }
                .scale-line-plate {
                  height: calc(14px * var(--scaleY));
                  margin: calc(-4px * var(--scaleY)) calc(8px * var(--scaleX));
                  display: flex;
                  justify-content: space-between;
                  .scale-line-common {
                    width: calc(2px * var(--scaleX));
                    height: 100%;
                  }
                  .scale-line-special-1 {
                    background: #e60012;
                  }
                  .scale-line-special-2 {
                    background: #f7ab00;
                  }
                  .scale-line-special-3 {
                    background: #fff100;
                  }
                  .scale-line-special-4 {
                    background: #02f061;
                  }
                }
              }
              .scale-value-plate {
                margin: calc(7px * var(--scaleY)) calc(22px * var(--scaleX)) 0 calc(28px * var(--scaleX));
                display: flex;
                justify-content: space-between;
                .scale-value-common {
                  line-height: calc(17px * var(--scaleY));
                  font-size: calc(20px * var(--scaleFontRelative));
                  color: #ffffff;
                }
                .scale-value-special-2, .scale-value-special-3 {
                  margin-left: calc(7px * var(--scaleX));
                }
              }
            }
          }
          .button-container {
            display: flex;
            flex-wrap: wrap;
            .operate-button {
              width: calc(var(--singleButtonWidth) * var(--scaleX));
              margin-top: calc(10px * var(--scaleY));
              font-size: calc(var(--buttonRelatedFontSize) * var(--scaleFontRelative));
              color: #ffffff;
              border: none;
              background-color: #ffffff00;
              background-repeat: no-repeat;
              background-size: 100% 100%;
              cursor: pointer;
              &:hover {
                font-weight: bold;
              }
              &:nth-child(3n+2) {
                margin-right: calc(var(--singleButtonMarginRight) * var(--scaleX));
                margin-left: calc(var(--singleButtonMarginLeft) * var(--scaleX));
              }
            }
          }
          .button-container-single-row {
            justify-content: center;
          }
          .button-container-multi-row {
            justify-content: flex-start;
          }
        }
        .pager-container {
          height: calc(var(--pagerHeight) * var(--scaleY));
          position: absolute;
          color: #ffffff;
          font-size: calc(28px * var(--scaleFontRelative));
          display: flex;
          justify-content: center;
          align-items: center;
          .pager-button {
            width: calc(30px * var(--scaleX));
            height: calc(30px * var(--scaleY));
            transition: transform .6s;
            cursor: pointer;
            &:hover {
              transform: scale(1.3);
            }
          }
          .pager-button-back {
            margin-right: calc(15px * var(--scaleX));
            background-repeat: no-repeat;
            background-size: 100% 100%;
            background-image: url('~@/assets/map/map-popup/common/pager-back.png');
          }
          .pager-button-next {
            margin-left: calc(15px * var(--scaleX));
            background-repeat: no-repeat;
            background-size: 100% 100%;
            background-image: url('~@/assets/map/map-popup/common/pager-next.png');
          }
        }
      }
    }
  }
}
.map-graphic-search-summary {
  max-width: calc(600px * var(--scaleX));
  line-height: calc(45px * var(--scaleY));
  font-size: calc(33px * var(--scaleFontRelative));
  text-align: center;
  .content {
    position: relative;
    left: calc(-50% + 50px * var(--scaleX));
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url('~@/assets/map/map-icon/map-icon-popup.png');
    display: flex;
    z-index: 1;
    .title {
      padding: calc(20px * var(--scaleY)) calc(5px * var(--scaleX)) calc(35px * var(--scaleY)) calc(35px * var(--scaleX));
      color: #ffffff;
      .summary {
        font-weight: bold;
        color: #03ff32;
      }
    }
    .mark {
      width: calc(50px * var(--scaleX));
      height: calc(50px * var(--scaleY));
      margin: calc(20px * var(--scaleY)) calc(35px * var(--scaleX)) calc(35px * var(--scaleY)) calc(5px * var(--scaleX));
      background-repeat: no-repeat;
      background-size: 100% 100%;
      background-image: url('~@/assets/map/map-icon/map-icon-right-arrow.png');
      cursor: pointer;
      &:hover {
        transform: scale(1.1);
      }
    }
  }
  .icon {
    width: calc(70px * var(--scaleX));
    height: calc(70px * var(--scaleY));
    position: absolute;
    bottom: calc(-35px * var(--scaleY));
    margin-left: calc(50% - 35px * var(--scaleX));
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url('~@/assets/map/map-icon/map-icon-classic.png');
  }
}
</style>
